Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

Code Block
public class UserDAOImpl implements UserDAO {
   @Inject
   @PersistenceContext(unitName = "DemoUnit")
   private EntityManager entityManager;

   ...
}

Transaction management

As you already know from the Hibernate integration library, Tapestry automatically manages transactions for you. The JPA integration library defines the @CommitAfter _annotation, which acts as the correspondent annotation from the Hibernate integration library. Let’s explore the _UserDAO interface to see the annotation in action.

Code Block
public interface UserDAO {

   @CommitAfter
   @PersistenceContext(unitName = "DemoUnit")
   void add(User user);

   List<User> findAll();

   @CommitAfter
   @PersistenceContext(unitName = "DemoUnit")
   void delete(User... users);
}

As you can see, the annotation may be placed on service method in order to mark that method as transactional. Any method marked with @CommitAfter annotation will have a transaction started before, and committed after it is called. Runtime exceptions thrown by by a transactional method will abort the transaction. Checked exceptions are ignored and the transaction will be committed anyway.

Warning

Note that EntityTransaction interface does not support two phase commit. Committing transactions of multiple EntityManagers in the same request might result in data consistency issues. That’s why @CommitAfter annotation must be accompanied by the @PersistenceContext annotation if multiple persistence unit are defined in an application. This way you can only commit the transaction of a single persistence unit. You should be very carefully, if you are committing multiple transactions manually in the same request.

After placing the @CommitAfter annotation on methods, you need to tell Tapestry to advise those methods. This is accomplished by adding the transaction advice, as shown in the following example.

Code Block
public class AppModule {

   @Match("*DAO")
   public static void adviseTransactionally(
         JpaTransactionAdvisor advisor,
         MethodAdviceReceiver receiver) {

      advisor.addTransactionCommitAdvice(receiver);
   }
}