/** * junit-rules: JUnit Rules Library * * Copyright (c) 2009-2011 by Alistair A. Israel. * This software is made available under the terms of the MIT License. * * Created Oct 22, 2009 */ package junit.rules.jpa.hibernate; import static junit.rules.jpa.hibernate.DerbyHibernateUtil.JDBC_DERBY_URL; import static junit.rules.util.Reflection.invoke; import static junit.rules.util.Reflection.set; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.sql.DriverManager; import java.sql.SQLException; import java.util.List; import javax.annotation.PostConstruct; import javax.persistence.EntityManager; import javax.persistence.EntityManagerFactory; import javax.persistence.PersistenceContext; import junit.rules.dbunit.DbUnitUtil; import junit.rules.dbunit.FixturesUtil; import org.apache.derby.jdbc.EmbeddedDriver; import org.dbunit.JdbcDatabaseTester; import org.dbunit.dataset.CompositeDataSet; import org.dbunit.dataset.DataSetException; import org.dbunit.dataset.IDataSet; import org.hibernate.ejb.Ejb3Configuration; import org.junit.After; import org.junit.AfterClass; import org.junit.Before; import org.junit.BeforeClass; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * @author Alistair A. Israel */ public class DerbyHibernateTestCase { private static final Logger logger = LoggerFactory.getLogger(HibernatePersistenceContext.class); private static final ThreadLocal<EntityManagerFactory> ENTITY_MANAGER_FACTORY = new ThreadLocal<EntityManagerFactory>(); private EntityManager entityManager; private JdbcDatabaseTester jdbcDatabaseTester; /** * */ @BeforeClass public static void initializeDerbyHibernate() { final Ejb3Configuration configuration = DerbyHibernateUtil.configureDerbyHibernateJpa(); ENTITY_MANAGER_FACTORY.set(configuration.buildEntityManagerFactory()); } /** * */ @AfterClass public static void closeHibernateDerby() { ENTITY_MANAGER_FACTORY.get().close(); try { DriverManager.getConnection(JDBC_DERBY_URL + ";shutdown=true"); } catch (final SQLException e) { if (e.getErrorCode() == 45000 && "08006".equals(e.getSQLState())) { logger.info("Derby shut down normally"); } else { // if the error code or SQLState is different, we have // an unexpected exception (shutdown failed) throw new RuntimeException(e.getMessage(), e); } } } /** * @param object * an object to which we will apply EJB 3.0 style @PersistenceContext and @PostConstruct handling */ public final void injectAndPostConstruct(final Object object) { final Class<? extends Object> clazz = object.getClass(); for (final Field field : clazz.getDeclaredFields()) { if (field.isAnnotationPresent(PersistenceContext.class)) { final Class<?> type = field.getType(); if (type.equals(EntityManager.class)) { set(field).of(object).to(entityManager); } else { logger.warn("Found field \"{}\" annotated with @PersistenceContext " + "but is of type {}", field .getName(), type.getName()); } } } for (final Method method : clazz.getDeclaredMethods()) { if (method.isAnnotationPresent(PostConstruct.class)) { final int nParameters = method.getParameterTypes().length; if (nParameters == 0) { invoke(method).on(object); } else { logger.warn("Found method \"{}\" annotated @PostConstruct " + "but don't know how to invoke with {} parameters", method.getName(), nParameters); } } } } /** * @throws Throwable * on any throwable */ @Before public final void initializeDbUnit() throws Throwable { entityManager = ENTITY_MANAGER_FACTORY.get().createEntityManager(); jdbcDatabaseTester = new JdbcDatabaseTester(EmbeddedDriver.class.getName(), JDBC_DERBY_URL); final List<String> fixtureNames = FixturesUtil.getFixtureNames(getClass()); if (fixtureNames.isEmpty()) { logger.warn("No fixtures to load! Specify fixtures using @Fixtures."); } else { loadFixtures(fixtureNames); } jdbcDatabaseTester.onSetup(); } /** * @param fixtureNames * the fixture names * @throws DataSetException * on any exception */ private void loadFixtures(final List<String> fixtureNames) throws DataSetException { final IDataSet[] dataSets = DbUnitUtil.loadDataSets(fixtureNames); if (dataSets.length == 0) { logger.warn("Found 0 data sets!"); } else { final CompositeDataSet compositeDataSet = new CompositeDataSet(dataSets); jdbcDatabaseTester.setDataSet(compositeDataSet); } } /** * {@inheritDoc} * * @see junit.rules.TestFixture#tearDown() */ @After public final void tearDownDbUnit() throws Throwable { jdbcDatabaseTester.onTearDown(); } /** * @return {@link EntityManager} * @see javax.persistence.EntityManagerFactory#createEntityManager() */ public final EntityManager getEntityManager() { return this.entityManager; } }