import javax.persistence.Persistence;
import javax.persistence.PersistenceException;
+import org.wamblee.general.ThreadSpecificProxyFactory;
import org.wamblee.test.jndi.StubInitialContextFactory;
+import org.wamblee.test.transactions.TransactionResource;
/**
* Utility for building an appropriately configured EntityManagerFactory. The
* The other purpose is to to shield dependencies of the test code on a
* particular JPA provider.
*/
-public class JpaBuilder {
+public class JpaBuilder implements TransactionResource<EntityManager> {
private static final Logger LOGGER = Logger.getLogger(JpaBuilder.class
.getName());
}
private PersistenceUnitDescription persistenceUnit;
- private String url;
- private String user;
- private String password;
+ private String url;
+ private String user;
+ private String password;
private EntityManagerFactory factory;
-
+ private ThreadSpecificProxyFactory<EntityManager> entityManager;
+
/**
* Constructs the builder.
*
- * @param aUrl JDBC URL
- * @param aUser User name
- * @param aPassword Password.
+ * @param aUrl
+ * JDBC URL
+ * @param aUser
+ * User name
+ * @param aPassword
+ * Password.
* @param aPersistenceUnit
* Persistence unit.
*/
public JpaBuilder(String aUrl, String aUser, String aPassword,
PersistenceUnitDescription aPersistenceUnit) {
persistenceUnit = aPersistenceUnit;
- url = aUrl;
- user = aUser;
- password = aPassword;
+ url = aUrl;
+ user = aUser;
+ password = aPassword;
+ entityManager = new ThreadSpecificProxyFactory<EntityManager>(EntityManager.class);
}
/**
*/
public EntityManagerFactory createFactory() {
Map<String, String> jpaProps = new TreeMap<String, String>();
-
+
jpaProps.put("javax.persistence.jtaDataSource", null);
jpaProps.put("javax.persistence.transactionType", "RESOURCE_LOCAL");
jpaProps.put("javax.persistence.jdbc.url", url);
JpaCustomizerBuilder.getCustomizer().customize(persistenceUnit,
jpaProps);
-
+
// jpaProps.put("javax.persistence.provider",
// HibernatePersistence.class.getName());
EntityManagerFactory emf = Persistence.createEntityManagerFactory(
* @return The return value of the execute method of the unit of work.
*/
public <T> T execute(JpaUnitOfWork<T> aWork) throws Exception {
- EntityManager em = factory.createEntityManager();
- EntityTransaction transaction = em.getTransaction();
- transaction.begin();
+ EntityManager em = begin();
try {
T value = aWork.execute(em);
- transaction.commit();
+ commit(em);
return value;
} catch (Exception e) {
LOGGER.log(Level.WARNING, "Exception occured", e);
- transaction.rollback();
+ rollback(em);
throw e;
+ }
+ }
+
+ @Override
+ public EntityManager begin() {
+ EntityManager em = factory.createEntityManager();
+ EntityTransaction transaction = em.getTransaction();
+ transaction.begin();
+ entityManager.set(em);
+ return em;
+ }
+
+ @Override
+ public void commit(EntityManager aEntityManager) {
+ try {
+ aEntityManager.getTransaction().commit();
} finally {
- em.close();
+ aEntityManager.close();
+ entityManager.set(null);
}
}
+
+ @Override
+ public void rollback(EntityManager aEntityManager) {
+ try {
+ aEntityManager.getTransaction().rollback();
+ } finally {
+ 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.
+ */
+ public EntityManager getContextualEntityManager() {
+ return entityManager.getProxy();
+ }
}
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- */
+ */
package org.wamblee.test.persistence;
import static junit.framework.Assert.*;
}
+ @Test
+ public void testEntityPersistenceWithBasicApi() throws Exception {
+
+ // Use the JPA builder to create a transaction scoped entity manager for
+ // as and execute the
+ // unit of work.
+ EntityManager em = builder.begin();
+
+ MyEntity entity = new MyEntity("a", "b");
+ em.persist(entity);
+
+ builder.commit(em);
+
+ // Verify one row is written (using Db unit)
+ ITable table = dbtester.getDataSet().getTable("XYZ_MYENTITY");
+ assertEquals(1, table.getRowCount());
+
+ assertEquals("a", table.getValue(0, "SLEUTELTJE"));
+ assertEquals("b", table.getValue(0, "VALUE"));
+
+ // For this simple test, it can also be done through DatabaseUtils
+ assertEquals(1, dbutils.getTableSize("XYZ_MYENTITY"));
+
+ }
+
+ @Test
+ public void testEntityPersistenceWithContextualEntityManager() throws Exception {
+
+ // Use the JPA builder to create a transaction scoped entity manager for
+ // as and execute the
+ // unit of work.
+ builder.begin();
+
+ EntityManager em = builder.getContextualEntityManager();
+ MyEntity entity = new MyEntity("a", "b");
+ em.persist(entity);
+
+ builder.commit(em);
+
+ // Verify one row is written (using Db unit)
+ ITable table = dbtester.getDataSet().getTable("XYZ_MYENTITY");
+ assertEquals(1, table.getRowCount());
+
+ assertEquals("a", table.getValue(0, "SLEUTELTJE"));
+ assertEquals("b", table.getValue(0, "VALUE"));
+
+ // For this simple test, it can also be done through DatabaseUtils
+ assertEquals(1, dbutils.getTableSize("XYZ_MYENTITY"));
+
+ }
}