...
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);
}
} |