Moving on we will have these steps:
1. Pre-requisites
2. Setting up the application context
3. Writing Domain and DAO interface
4. Writing DAO unit tests
5. Writing DAO implementations
I will cover 1 and 2 in this part to have the framework in place. In the next part we will write our domain (just one) and dao interface, dao unit test and then dao implementation. This is a logical order because we would want to test first an then see what we need in order for the test to pass. That 'what we need' will go into our implementation. This is called, as you might have guessed it, Test Driven Approach.
Pre-requisites
* Spring Core library for dependency injection. We are also going to use SpringJunit4ClassRunner for unit testing.
* Hibernate 3.x. We will be using Hibernate's Criteria, specifically, Detached Criteria. For more info on using Criteria look here.
* MySQL db.
You can use Maven to configure all of these. Here's what part of the pom.xml looks like. If you need more help on configuring a maven project please look at my "How to setup a Maven Java Enterprise Application". You can find that under the category "Deployment". Here's the list of artifacts you'll need:
<dependency>
<groupId>commons-dbcp</groupId>
<artifactId>commons-dbcp</artifactId>
<version>1.2.2</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>3.3.2.GA</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-annotations</artifactId>
<version>3.3.1.GA</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-commons-annotations</artifactId>
<version>3.3.0.ga</version>
</dependency>
<dependency>
<groupId>javassist</groupId>
<artifactId>javassist</artifactId>
<version>3.6.0.GA</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-jcl</artifactId>
<version>1.5.8</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.16</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${spring.framework.version}</version> <!--version 3.0.5.RELEASE -->
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.framework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>${spring.framework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.framework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>${spring.framework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>${spring.framework.version}</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.14</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.7</version>
</dependency>
Setting up the Application Context
When the test is run, it will scan the application context to inject the dao interface. The implementation of the dao interface will use Hibernate's sessionFactory to run our Hibernate queries. We will also add our single Item domain/entity to use sessionFactory. That object will be directly mapped to the ITEM table of our db. I will not create the table since this is simple enough. Lastly, we will need to use Transactions in order to rollback our unit test methods. For this, we will annotate our test methods as @Transactional. Below is the applicationContext.xml.
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">
<!-- This is where the properties related to datasource are read from -->
<bean id="propertyConfigurer">
<property name="location" value="classpath:hibernate.properties" />
<property name="ignoreUnresolvablePlaceholders" value="false" />
</bean>
<!-- Define dataSource to use -->
<bean id="dataSource">
<property name="driverClassName" value="${hibernate.jdbc.driver}" /> <!-org.gjt.mm.mysql.Driver -->
<property name="url" value="${hibernate.jdbc.url}" />
<property name="username" value="${hibernate.jdbc.user}" />
<property name="password" value="${hibernate.jdbc.password}" />
</bean>
<!-- The sessionFactory will scan the domain objects and their annotated relationships. -->
<bean id="sessionFactory">
<property name="dataSource" ref="dataSource" />
<property name="annotatedClasses">
<list>
<value>com.company.application.core.domain.Item</value>
..............
</list>
</property>
<property name="schemaUpdate" value="true" />
<property name="hibernateProperties">
<props>
<prop key="hibernate.connection.isolation">2</prop>
<prop key="hibernate.bytecode.use_reflection_optimizer">true</prop>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
<prop key="hibernate.jdbc.batch_size">20</prop>
<prop key="hibernate.max_fetch_depth">2</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.format_sql">true</prop>
</props>
</property>
</bean>
<!-- Define Transaction Manager. We will use Hibernate Transaction Manager. -->
<bean id="transactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<!-- We will set transactional properties with annotation -->
<tx:annotation-driven />
<bean id="itemDao">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
</beans>
One thing you might have noticed is that I could easily annotated my Dao as @Resource, have it scanned and not defined in the xml above. That is perfectly legal. Now we're set to write our domain, dao interface, dao test and dao implementation.
Hi there, You have done a fantastic job. I'll certainly digg it and individually recommend to my friends. I am confident they'll be benefited from this web site.
ReplyDeleteGood to hear this. Thanks!
ReplyDeletei bookmarked you in my browser admin thank you so much i will likely be searching for your upcoming posts
ReplyDeleteThanks like your Unit Testing Hibernate Data Access Objects using JUnit 4 – Part I 20k lines and refactoring
ReplyDeleteYour way of describing everything in this article is really fastidious, all be able to effortlessly know it, Thanks a lot.
ReplyDeleteI think this is among the most important info for me. And i am glad reading your article. But want to remark on few general things, The web site style is ideal, the articles is really nice : D. Good job, cheers
ReplyDelete