import org.wamblee.general.ThreadSpecificProxyFactory;
import org.wamblee.test.jndi.StubInitialContextFactory;
import org.wamblee.test.transactions.TransactionResource;
+import org.wamblee.test.transactions.TransactionResult;
/**
* Utility for building an appropriately configured EntityManagerFactory. The
private String user;
private String password;
private EntityManagerFactory factory;
- private ThreadSpecificProxyFactory<EntityManager> entityManager;
-
+ private ThreadSpecificProxyFactory<EntityManager> entityManager;
+
/**
* Constructs the builder.
*
url = aUrl;
user = aUser;
password = aPassword;
- entityManager = new ThreadSpecificProxyFactory<EntityManager>(EntityManager.class);
+ entityManager = new ThreadSpecificProxyFactory<EntityManager>(
+ EntityManager.class);
}
/**
* passing it the entity manager. Use of this method saves a lot of typing
* for applications.
*
+ * This method requires the transaction to succeed. Otherwise the test will
+ * fail. See {@link #execute(JpaUnitOfWork, TransactionResultCallback)} and
+ * {@link RequireTransactionStatus} for more possibilities.
+ *
* @param aWork
* Work to execute.
+ *
* @return The return value of the execute method of the unit of work.
*/
public <T> T execute(JpaUnitOfWork<T> aWork) throws Exception {
+ return execute(aWork, new RequireTransactionStatus(
+ TransactionResult.COMMIT));
+ }
+
+ /**
+ * Executes a unit of work. This creates an entitymanager and runs the
+ * {@link JpaUnitOfWork#execute(EntityManager)} within a transaction,
+ * passing it the entity manager. Use of this method saves a lot of typing
+ * for applications.
+ *
+ * @param aWork
+ * Work to execute.
+ * @param aTransactionResultCallback
+ * callback to notify of the result of the transaction.
+ *
+ * @return The return value of the execute method of the unit of work.
+ */
+ public <T> T execute(JpaUnitOfWork<T> aWork,
+ TransactionResultCallback aCallback) throws Exception {
EntityManager em = begin();
try {
T value = aWork.execute(em);
- commit(em);
+ TransactionResult result = commit(em);
+ aCallback.status(result);
return value;
} catch (Exception e) {
LOGGER.log(Level.WARNING, "Exception occured", e);
- rollback(em);
+ TransactionResult result = rollback(em);
+ aCallback.status(result);
throw e;
- }
+ }
}
@Override
}
@Override
- public void commit(EntityManager aEntityManager) {
+ public TransactionResult commit(EntityManager aEntityManager) {
try {
- aEntityManager.getTransaction().commit();
+ EntityTransaction transaction = aEntityManager.getTransaction();
+ if (transaction.isActive()) {
+ if (transaction.getRollbackOnly()) {
+ transaction.rollback();
+ return TransactionResult.ROLLBACK;
+ }
+ transaction.commit();
+ return TransactionResult.COMMIT;
+ }
+ return TransactionResult.UNKNOWN;
} finally {
aEntityManager.close();
entityManager.set(null);
}
@Override
- public void rollback(EntityManager aEntityManager) {
+ public TransactionResult rollback(EntityManager aEntityManager) {
try {
- aEntityManager.getTransaction().rollback();
+ EntityTransaction transaction = aEntityManager.getTransaction();
+ if (transaction.isActive()) {
+ transaction.rollback();
+ return TransactionResult.ROLLBACK;
+ }
+ return TransactionResult.UNKNOWN;
} finally {
- aEntityManager.close();
+ if (aEntityManager.isOpen()) {
+ aEntityManager.close();
+ }
entityManager.set(null);
}
}
-
+
/**
- * Gets a contextual reference to an entity manager that delegates to the
- * appropriate (current) one which is active for the current transaction.
- * @return EntityManager.
+ * Gets a contextual reference to an entity manager that delegates to the
+ * appropriate (current) one which is active for the current transaction.
+ *
+ * @return EntityManager.
*/
- public EntityManager getContextualEntityManager() {
- return entityManager.getProxy();
+ public EntityManager getContextualEntityManager() {
+ return entityManager.getProxy();
}
}