Control your hibernate dependencies when you test your DAO layer

If you test your database access logic then you will overcome the issue of having many constraints related to twisted business logic. If you test an entity that is dependent on another entity that itself is dependent on many other entities you will end up requiring all hibernate mappings. It will slow you down because tests execute slower and you have to setup things that you don’t mind in your context. A naive solution is to manipulate your mappings in some way. I created a testutility class that targets crobbing not requiring dependencies.

Hibernate configuration helper

It is published under MIT license so you can use it for free. It’s part of my testutils github repository that for now doesn't contain much more. But time will pass and I’ll add other useful utilities. If it’s packed enough then I will also publish it to the public maven central repository.

How to use it

To modify your dependencies at runtime you have to define your hibernate configuration using the hibernate Configuration object.

Configuration configuration = new Configuration()  
   .setProperty("hibernate.dialect", "org.hibernate.dialect.HSQLDialect")
   .setProperty("hibernate.connection.driver_class", "org.hsqldb.jdbcDriver")
   .setProperty("hibernate.connection.url", "jdbc:hsqldb:mem:test")
   .setProperty("hibernate.connection.username", "sa")
   .setProperty("hibernate.connection.password", "")
   .setProperty("hibernate.show_sql", "true")
   .setProperty("hibernate.current_session_context_class", "thread")
// .addResource("Player.hbm.xml")
// .addResource("PlayerText.hbm.xml")
   .setProperty("hibernate.hbm2ddl.auto", "create-drop");

   removeNotExistingConstraints(configuration);

   sf = configuration.buildSessionFactory();

   Session session = sf.getCurrentSession();

Instead of adding your hibernate mapping resources to your configuration you add them to the helper utility class.

private static void removeNotExistingConstraints(Configuration configuration) {  
   HibernateConfigurationHelper configHelper = 
      new HibernateConfigurationHelper();
   configHelper.addResource("Player.hbm.xml");
   //configHelper.addResource("PlayerText.hbm.xml");
   configHelper.addAllResourcesToConfiguration(configuration);
}

All non-existent dependencies will be removed. My unmodified Player.hbm.xml contains the constraint to the PlayerText entity:

<!DOCTYPE hibernate-mapping PUBLIC  
   "-//Hibernate/Hibernate Mapping DTD//EN"
   "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" >

<hibernate-mapping>  
   <class name="com.journerist.exampleForCleanArchitecture.entity.Player" table="PLAYER">
   <id name="playerId" column="PLAYER_ID" >
      <generator class="native"/>
   </id>
   <property name="username">
      <column name="USERNAME" />
   </property>
   <property name="points">
      <column name="POINTS"/>
   </property>

   <property name="gameCount">
      <column name="GAME_COUNT"/>
   </property>
   <property name="createdDate" type="date">
      <column name="CREATED_DATE"/>
   </property>
   <set name="playerTexts" table="PLAYER_TEXT"
      inverse="true" lazy="true" fetch="select">
      <key>
         <column name="TEXT_ID" not-null="true" />
      </key>
      <one-to-many class="com.journerist.exampleForCleanArchitecture.entity.PlayerText" />
   </set>
   </class>
</hibernate-mapping>

If you don’t add PlayerText.hbm.xml to the helper class then its dependency will be removed:

<!DOCTYPE hibernate-mapping PUBLIC  
   "-//Hibernate/Hibernate Mapping DTD//EN"
   "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" >

<hibernate-mapping>  
   <class name="com.journerist.exampleForCleanArchitecture.entity.Player" table="PLAYER">
   <id name="playerId" column="PLAYER_ID" >
      <generator class="native"/>
   </id>
   <property name="username">
      <column name="USERNAME" />
   </property>
   <property name="points">
      <column name="POINTS"/>
   </property>

   <property name="gameCount">
      <column name="GAME_COUNT"/>
   </property>
   <property name="createdDate" type="date">
      <column name="CREATED_DATE"/>
   </property>
   </class>
</hibernate-mapping>  

In terms of testing, your entities don’t need to be changed. Inserts don’t mind the existing relationship.

For now the hibernate configuration helper contains different replacement strategies. These are simple regular expressions that replace the dependency when found. If you want to add more or other experessions then you can create your own and easily add them as a strategy. It goes through all given strategies and executes them all one by one.

You can also create a pull request, but keep it in mind to test your strategy. There is a connected travis-CI build server that constantly makes sure that everything works.
Have fun testing your low-level database logic.

Journerist

Read more posts by this author.