I would like to write a unit test to see if my serialization of lazy loaded elements worked.
My key problem there is to close a session and reopen it while using the OpenSessionInViewInterceptor.
What I would like to do:
- insert the values in the database
- close Transaction and session
- open new session and transaction
- load elements which contain lazy loaded elements
- generate json with a hibernateAwareObjectMapper
- verify the json
It seems that the session needs to be attached to the current thread.
the following error is thrown: Any ideas?
Code:
2011-12-02 19:39:06,526 [main] WARN org.springframework.test.context.TestContextManager - Caught exception while allowing TestExecutionListener [org.springframework.test.context.transaction.TransactionalTestExecutionListener@13cb8654] to process 'after' execution for test: method [public void de.company.backend.spring.TestLazyLoadingJsonSerialization.testLazyLoadingSerialisation()], instance [de.company.backend.spring.TestLazyLoadingJsonSerialization@16dffef3], exception [null]
java.lang.IllegalStateException: No value for key [org.hibernate.impl.SessionFactoryImpl@91bee48] bound to thread [main]
at org.springframework.transaction.support.TransactionSynchronizationManager.unbindResource(TransactionSynchronizationManager.java:199)
at org.springframework.orm.hibernate3.HibernateTransactionManager.doCleanupAfterCompletion(HibernateTransactionManager.java:710)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.cleanupAfterCompletion(AbstractPlatformTransactionManager.java:1011)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.processRollback(AbstractPlatformTransactionManager.java:877)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.rollback(AbstractPlatformTransactionManager.java:822)
at org.springframework.test.context.transaction.TransactionalTestExecutionListener$TransactionContext.endTransaction(TransactionalTestExecutionListener.java:512)
at org.springframework.test.context.transaction.TransactionalTestExecutionListener.endTransaction(TransactionalTestExecutionListener.java:290)
at org.springframework.test.context.transaction.TransactionalTestExecutionListener.afterTestMethod(TransactionalTestExecutionListener.java:183)
at org.springframework.test.context.TestContextManager.afterTestMethod(TestContextManager.java:406)
at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:90)
at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:72)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:231)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184)
at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:174)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
my code:
app-context.xml
Code:
<mvc:interceptors>
<bean class="org.springframework.orm.hibernate3.support.OpenSessionInViewInterceptor">
<property name="sessionFactory" ref="sessionFactory" />
<property name="flushModeName">
<value>FLUSH_AUTO</value>
</property>
</bean>
</mvc:interceptors>
code for closing and reopen session
Code:
{
//restart session and transaction
commitTransaction();
stopSession();
startSession();
startTransaction();
}
private void commitTransaction() {
Session session = SessionFactoryUtils.getSession(sessionFactory, false);
if (session != null) {
session.getTransaction().commit();
}
}
private void rollbackTransaction() {
Session session = SessionFactoryUtils.getSession(sessionFactory, false);
if (session != null) {
session.getTransaction().rollback();
}
}
private void startTransaction() {
Session session = SessionFactoryUtils.getSession(sessionFactory, false);
if (session != null) {
session.beginTransaction();
}
}
private void stopSession() {
Session session = SessionFactoryUtils.getSession(sessionFactory, false);
if (session != null) {
SessionFactoryUtils.closeSession(session);
}
}
private void startSession() {
Session session = SessionFactoryUtils.getSession(sessionFactory, true);
}
the test
Code:
@Test
public void testLazyLoadingSerialisation() {
HibernateAwareObjectMapper mapper = new HibernateAwareObjectMapper();
String json = "";
try {
json = mapper.writeValueAsString(returnMatchedRide);
} catch (Exception e) {
e.printStackTrace();
fail("mapping exception");
}
assertEquals(false, json.contains("\"route\":null\""));
}
HiberrnateAwareObjectMapper based on com.fasterxml.jackson.module.hibernate.HibernateModule.HibernateModule()
Code:
public class HibernateAwareObjectMapper extends ObjectMapper {
public HibernateAwareObjectMapper() {
AnnotationIntrospector introspector = new JacksonAnnotationIntrospector();
getDeserializationConfig().setAnnotationIntrospector(introspector);
getSerializationConfig().setAnnotationIntrospector(introspector);
HibernateModule hm = new HibernateModule();
registerModule(hm);
configure(Feature.WRITE_ENUMS_USING_TO_STRING, true);
setVisibilityChecker(getVisibilityChecker().with(
JsonAutoDetect.Visibility.NONE));
}
public void setPrettyPrint(boolean prettyPrint) {
configure(Feature.INDENT_OUTPUT, prettyPrint);
}
}