6

Can you call a method that requires a transaction inside a method that does not?

@TransactionAttribute(value = TransactionAttributeType.NEVER)
public void DoSomething(final List<Item> items) {

//can you call a method that requires a transaction here ?
for (Item i : items) {
    methodCall(item);

}

@TransactionAttribute(value = TransactionAttributeType.REQUIRES_NEW)
public void methodCall(final Item item) {
    // access lazily loaded item properties
    item.getSalesOrder();
    item.getAllocation();

    //throws org.hibernate.LazyInitializationException: could not initialize proxy - no Session

}

The .NEVER attribute says it will guarantee the method does not run inside a transaction but what about calls to other methods inside that method

Luke
  • 63
  • 1
  • 1
  • 4
  • You can apply the @TransactionAttribute annotation at the class-level to specify the default transaction attribute for all business methods of the enterprise bean. You can apply this annotation at the method-level to specify the transaction attribute for that method. Applying the annotation at the method-level overrides the class-level annotation (if any) for that method. – Luke Jun 23 '11 at 14:00

1 Answers1

11

The annotation only defines the required transaction state which must exist when the annotated method is invoked (in this case a transaction must not exist). It does not restrict what may occur within the execution of the annotation method. So within this method you could start a new transaction without any problem.

In the example that you provided, you may call a method which requires a transaction from within a method that has a transactional setting of NEVER. In this situation, a new transaction will be created for the method call that requires the transaction. If the inner method is marked with a MANDATORY setting, then the inner method call will fail as an existing transaction does not exist and the MANDATORY setting does not automatically create one for you.

Kris Babic
  • 6,254
  • 1
  • 29
  • 18
  • Thanks for clearing that up. I could see no reason why it would not work however I am unable to access lazily loaded properties inside the inner method invocation (even though it is annotated with requires new) – Luke Jun 23 '11 at 16:42
  • How did your top level bean get access to the inner bean (`itemBean`)? Is `itemBean` container managed as well or did you directly instantiate it (transaction annotations are only supported on managed beans)? Also, what are the lazy loaded properties to which you are referring and how are they associated with the transaction (if at all)? – Kris Babic Jun 23 '11 at 16:58
  • Each item has a salesorder and an allocation which are lazily loaded as well as other properties that are unrelated to this particular transaction. In this case both methods are on the same bean, so my code example should not have had the itemBean prefix. – Luke Jun 24 '11 at 08:27
  • 2
    Having re-read the question and your answer it became obvious that the call to the second (inner) method was a regular method call and not handled by the EJB container. answered here http://stackoverflow.com/questions/427452/ejb-transactions-in-local-method-calls – Luke Jun 24 '11 at 10:21