• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Liutauras Vilda
  • Jeanne Boyarsky
  • Devaka Cooray
  • Paul Clapham
Sheriffs:
  • Tim Cooke
  • Knute Snortum
  • Bear Bibeault
Saloon Keepers:
  • Ron McLeod
  • Tim Moores
  • Stephan van Hulst
  • Piet Souris
  • Ganesh Patekar
Bartenders:
  • Frits Walraven
  • Carey Brown
  • Tim Holloway

about second stateful bean with a different Tx context than the first stateful bean

 
Ranch Hand
Posts: 1738
12
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
In this document :https://access.redhat.com/documentation/en-US/JBoss_Enterprise_Application_Platform/4.2/html/Hibernate_EntityManager_User_Guide/sect-Hibernate_EntityManager_User_Guide-EJB_container_environment-Persistence_context_propagation.html


If a stateful session bean with an extended persistence context instantiates another stateful session bean with an extended persistence context, the extended persistence context is inherited by the second stateful session bean. If the second stateful session bean is called with a different transaction context than the first, an IllegalStateException is thrown.



I created an example base on the book:





But when I tried this example, logTransaction2 is running in a different transaction than createEmployee2 , but it still works. I am not sure why.
The quote says the second stateful bean with extended pc running in a different transaction will get an exception.
 
Creator of Enthuware JWS+ V6
Posts: 3287
296
Android Eclipse IDE Chrome
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

But when I tried this example, logTransaction2 is running in a different transaction than createEmployee2 , but it still works. I am not sure why.
The quote says the second stateful bean with extended pc running in a different transaction will get an exception.


To make this work you should have two different clients each of them starting transaction (by calling a method) on the stateful session bean and then invoke the method that will invoke the other bean:

CL1 -> SFSB1.method1() in Transaction T1 with extended PersistenceContext1
CL2 -> SFSB2.method2() in Transaction T2 with extended PersistenceContext2

CL1 -> SFSB1.method3() which will invoke SFSB2.method4()

As soon as the SFSB2.method4() is called you will have the persistence context clash and receive an EJBException.
 
Himai Minh
Ranch Hand
Posts: 1738
12
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi, Frits. To demo what you described in the previous post:









I first call the method 1 by calling the servlet (client 1)  :http://localhost:8080/txScopedPersistenceContext/EmployeeServlet
Then, I call the method 2 by calling the second servlet (client2):http://localhost:8080/txScopedPersistenceContext/AuditServlet
Next, I click on the call audit button as shown in the diagram.
But what I get is EJB exception, not IllegalStateException as described:


If a stateful session bean with an extended persistence context instantiates another stateful session bean with an extended persistence context, the extended persistence context is inherited by the second stateful session bean. If the second stateful session bean is called with a different transaction context than the first, an IllegalStateException is thrown.

call_audit_bean_button.JPG
[Thumbnail for call_audit_bean_button.JPG]
 
Himai Minh
Ranch Hand
Posts: 1738
12
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
One more trial is that I remove the REQUIRES_NEW transaction attribute in method4 of audit service bean, I got a EJBTransactionRollbackException from method 4.
But it is still not a illegalStateException. I guess the document that I mentioned in the previous post is specific to JBoss.

 
Frits Walraven
Creator of Enthuware JWS+ V6
Posts: 3287
296
Android Eclipse IDE Chrome
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Interesting...

I would have expected an EJBException in your last setup or did method4() throw a IllegalArgumentException ? If that is the case then the outcome is correct because the client (EmployeeService) runs under the same transaction as the bean (AuditService) and a RuntimeException (= System Exception) is thrown from the latter. The RuntimeException is turned into ab EJBTransactionRollbackException by the container (check my EJB notes example 6.4).


This is what the specs say about the Persistence Context Propagation

7.6.3.1 Requirements for Persistence Context Propagation
...
If a component is called and the JTA transaction is propagated into that component:

  • If the component is a stateful session bean to which an extended persistence context has been bound and there is a different persistence context bound to the JTA transaction, an EJBException is thrown by the container.



  • According to the specs the extended PersistenceContext is created as soon as the Stateful Session Bean is created, but maybe JBoss pospones that until the first method is called on the EntityManager (like in a non-extended PersistenceContext). Try to persist an Entity in both method1 and method2 and see what happens.
     
    Himai Minh
    Ranch Hand
    Posts: 1738
    12
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Hi, Frits.
    I modified the code:



    Client 1  calls the employee servlet that persists employee 100.
    Client 2 calls the audit serlvet that persists employee 200.




    It throws EJBTransactionRollback exception when method3 calls method4 and employee 300 is not persisted as the transaction is rolled back.
    It is because audit bean throws the illegal argument exception saying employee 300 is not found. Why audit bean cannot find employee 300 ?
    It is because the persistence context from employee service bean cannot propagate to audit service bean. Audit bean is  using a different pc.


    Employee service: add employee 100
    2017-03-22T21:14:08.863-0400|Info: Looked up  audit service...
    2017-03-22T21:14:08.863-0400|Info: Audit service: add employee 200
    2017-03-22T21:14:13.071-0400|Info: Employee service: add employee 100
    2017-03-22T21:14:13.071-0400|Info: Employee service bean asks audit service bean to find employee 300 created in m3:
    2017-03-22T21:14:13.080-0400|Warning: A system exception occurred during an invocation on EJB AuditService, method: public void examples.stateless.AuditService.method4(int)
    2017-03-22T21:14:13.080-0400|Warning: javax.ejb.TransactionRolledbackLocalException: Exception thrown from bean
    at com.sun.ejb.containers.EJBContainerTransactionManager.checkExceptionClientTx(EJBContainerTransactionManager.java:662)
     ...
    at examples.stateless.__EJB31_Generated__AuditService__Intf____Bean__.method4(Unknown Source)
    at examples.stateless.EmployeeService.method3(EmployeeService.java:55)
    ...
    Caused by: java.lang.IllegalArgumentException: Unknown employee id in method 4.
    at examples.stateless.AuditService.method4(AuditService.java:56)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

     
    Himai Minh
    Ranch Hand
    Posts: 1738
    12
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    One more modification:


    Employee service: add employee 100
    2017-03-22T21:31:12.636-0400|Info: Looked up  audit service...
    2017-03-22T21:31:12.638-0400|Info: Audit service: add employee 200
    2017-03-22T21:31:16.864-0400|Info: Employee service: add employee 100
    2017-03-22T21:31:16.864-0400|Info: Employee service bean asks audit service bean to find employee 300 created in m3:
    2017-03-22T21:31:16.880-0400|Info: Audit service also found employee id 300
    2017-03-22T21:31:16.880-0400|Info: Employee service bean asks audit service bean to find employee 100 created in m1:
    2017-03-22T21:31:16.880-0400|Info: Audit service also found employee id 100
    2017-03-22T21:31:16.880-0400|Info: Employee service bean asks audit service bean to find employee 200 created in m2:
    2017-03-22T21:31:16.880-0400|Info: Audit service also found employee id 200



    The employee service bean persists employee 300. Then, the audit bean can find this employee 300.  
    The pc of employee service bean propagates to the audit bean.
    Audit bean can find employee 100 because it has been in the DB already.
     
    Himai Minh
    Ranch Hand
    Posts: 1738
    12
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    I made one more modification to the audit bean:

    To my surprise, it works:


    Employee service: add employee 100
    2017-03-22T21:36:52.546-0400|Info: Looked up  audit service...
    2017-03-22T21:36:52.546-0400|Info: Audit service: add employee 200
    2017-03-22T21:36:56.637-0400|Info: Employee service: add employee 100
    2017-03-22T21:36:56.637-0400|Info: Employee service bean asks audit service bean to find employee 300 created in m3:
    2017-03-22T21:36:56.637-0400|Info: Audit service also found employee id 300
    2017-03-22T21:36:56.637-0400|Info: Employee service bean asks audit service bean to find employee 100 created in m1:
    2017-03-22T21:36:56.637-0400|Info: Audit service also found employee id 100
    2017-03-22T21:36:56.637-0400|Info: Employee service bean asks audit service bean to find employee 200 created in m2:
    2017-03-22T21:36:56.637-0400|Info: Audit service also found employee id 200



    But the document says this:
    If a stateful session bean with an extended persistence context instantiates another stateful session bean with an extended persistence context, the extended persistence context is inherited by the second stateful session bean. If the second stateful session bean is called with a different transaction context than the first, an IllegalStateException is thrown.

    By the way, the document is from JBoss Hibernate, not from JSR 317.
    https://access.redhat.com/documentation/en-US/JBoss_Enterprise_Application_Platform/4.2/html/Hibernate_EntityManager_User_Guide/sect-Hibernate_EntityManager_User_Guide-EJB_container_environment-Persistence_context_propagation.html
     
    Don't get me started about those stupid light bulbs.
    • Post Reply Bookmark Topic Watch Topic
    • New Topic
    Boost this thread!