package com.tddinaction.data.hibernate.util; import java.io.IOException; import java.io.InputStream; import java.sql.Connection; import java.util.Arrays; import java.util.HashSet; import java.util.Properties; import java.util.Set; import org.hibernate.SessionFactory; import org.hibernate.cfg.Configuration; import org.junit.Assert; import com.tddinaction.data.util.SqlExecutor; /** * A base class for database integration tests giving access to a singleton * <tt>SessionFactory</tt> configured programmatically. * * @author Lasse Koskela */ public abstract class IncrementalHibernateIntegrationTestCase { private static SessionFactory sf; private static Set<Class> knownClasses = new HashSet<Class>(); /** * Returns a <tt>SessionFactory</tt> which knows about the persistent * classes passed in as parameters. A new <tt>SessionFactory</tt> instance * is only created if there is no existing instance or if some of the * classes passed in as parameters were not already configured for the * existing instance. * * @param persistentClasses * The persistent classes the <tt>SessionFactory</tt> should * know how to persist. There must be a "[ClassName].hbm.xml" * mapping document located in the classpath next to the class * file itself. * @return A <tt>SessionFactory</tt> that can be used for persisting the * classes passed in as arguments. */ protected static synchronized SessionFactory getSessionFactory( Class... persistentClasses) { Set<Class> newClasses = new HashSet<Class>(knownClasses); newClasses.addAll(Arrays.asList(persistentClasses)); if (sf == null || !newClasses.equals(knownClasses)) { try { Configuration cfg = createConfiguration(newClasses); sf = cfg.buildSessionFactory(); knownClasses = newClasses; } catch (Throwable ex) { throw new RuntimeException(ex); } } return sf; } /** * Loads a database schema into the integration test database from the DDL * statements in the referred file. * * @param resource * The path to the DDL file in classpath. */ protected void createSchema(String resource) throws Exception { InputStream schema = getClass().getResourceAsStream(resource); Assert.assertNotNull("Resource not found: " + resource, schema); Connection connection = sf.openSession().connection(); new SqlExecutor(connection).execute(schema); connection.commit(); connection.close(); } private static Configuration createConfiguration( Set<Class> persistentClasses) throws IOException { Configuration cfg = new Configuration(); String path = "/hibernate.test.properties"; Properties properties = loadPropertiesFrom(path); cfg.setProperties(properties); for (Class c : persistentClasses) { cfg.addClass(c); } return cfg; } private static Properties loadPropertiesFrom(String path) throws IOException { Class context = IncrementalHibernateIntegrationTestCase.class; InputStream stream = context.getResourceAsStream(path); Assert.assertNotNull("Resource not found: " + path, stream); Properties props = new Properties(); props.load(stream); return props; } }