Gettin' all Testy - The Spring TestContext, Hibernate, and you...
Tuesday, June 2, 2009 at 6:12AM I'm getting some materials ready around a project using the Hibernate Annotations API in Spring 2.5.6. The client is using Hibernate rather than straight JPA, likely due to wanting to get features such as Filters, Criteria, etc...
I've been used to JUnit 3.x for a while, but as I'm testing my Hibernate knowledge, I came across the newer Spring Test Context framework. If you install JUnit 4.4 (I'm using Maven, so I just added it as a test-time dependency) and also the spring test-context library, you'll have the ability to define tests that ramp up a Spring Context using the @ContextConfiguration annotation and coupled with extending a specific Spring abstract class, AbstractJUnit4SpringContextTests.
This is similar to the Junit 3.8 context configuration, but uses JUnit 4 semantics. Also you can use TestNG, just use a different abstract class. Here is a fragment:
@ContextConfiguration(locations = {"classpath:applicationContext.xml"})
public class HibernateModelTest
extends AbstractJUnit4SpringContextTests {
...
}
Ok, that's cool. You get an applicationContext member in the test class too. So, what if you wanted to interact with the Hibernate API directly? I've mounted my Hibernate configuration using the Spring Hibernate AnnotationSessionFactoryBean, scanning for entities in the org.rimple.example.domain package as in this example:
<bean id="mySessionFactory" class="org.springframework.orm.hibernate3.annotation.
AnnotationSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="packagesToScan" value="org.rimple.example.domain"/>
<property name="hibernateProperties">
<value>
hibernate.dialect=org.hibernate.dialect.HSQLDialect
hibernate.hbm2ddl.auto=create
hibernate.cache.provider_class=org.hibernate.cache.NoCacheProvider
hibernate.show_sql=true
hibernate.current_session_context_class=thread
hibernate.connection.pool_size=15
</value>
</property>
</bean>
Now I can just create a @Before and @After method to setup and tear down the session context. I can get fancy and begin a transaction and end it, just like the transactional tests provided for Repository tests, but then I can open and close and interact with the session myself.
private Session session;
@Before
public void setupSession() {
SessionFactory sessionFactory = (SessionFactory) applicationContext.
getBean("mySessionFactory");
session = sessionFactory.openSession();
session.getTransaction().begin();
}
@After
public void tearDownSession() {
session.getTransaction().rollback();
session.close();
}
Now, all I have to do is just interact with Hibernate directly. Given this Entity:
@Entity @Table(name="employees") public class Employee { @Id @GeneratedValue(strategy=GenerationType.AUTO) private Long id; @Column(nullable=false, length=30) private String firstName; @Column(nullable=false, length=30) private String lastName; @Column(nullable=false) private Boolean active; @Column(nullable=false) @Temporal(TemporalType.DATE) private Date hireDate; @Column(nullable=true) private String comments; ... }
We can use this test:
@Test
public void createEmployee() {
Employee e = new Employee();
e.setActive(true);
e.setFirstName("Joe");
e.setLastName("Smith");
e.setComments("A new employee");
e.setHireDate(new Date());
session.save(e);
assertNotNull(e);
}
QED! I am partial to the JPA Entity Manager and putting Hibernate behind a facade, but this works if your team decides they are using the Hibernate annotation and API instead.
Hibernate,
chariot-news,
spring in
Technologies 

Reader Comments