I have used Spring and Hibernate for years, but this is my first project using Spring 3 and Hibernate 4.
I set up the Model class such:
@Entity
@Table(name = "DICTIONARY_ENTRY", uniqueConstraints = @UniqueConstraint(columnNames = {
"DICTIONARY_UUID", "ANAGRAM", "WORD" }))
public class DictionaryEntry extends Pojo implements
Comparable<DictionaryEntry> {
@Column(name = "ANAGRAM", nullable = false)
private String anagram;
@Column(name = "WORD", nullable = false, unique = true)
private String word;
@Column(name = "DEFINITION", nullable = false)
private String definition;
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "DICTIONARY_UUID", referencedColumnName = "UUID", nullable=false)
private Dictionary dictionary;
@OneToMany(fetch = FetchType.LAZY, mappedBy = "fromEntry")
/*package*/ Set<CrossReference> fromReferences;
@OneToMany(fetch = FetchType.LAZY, mappedBy = "toEntry")
/*package*/ Set<CrossReference> toReferences;
Per the directions in the Spring manual, I then set up my DAO and inject in an instance of org.springframework.orm.hibernate4.LocalSessionFactoryBean. Then I call getSession() which is:
/**
* Get the current session for a hibernate query
* @return the current session
*/
protected Session getSession(){
return sessionFactory.getCurrentSession();
}
I then run my unit test, inject in my session factory and run this method:
object = (T) getSession().save(object);
Which throws:
org.hibernate.HibernateException: No Session found for current thread
at org.springframework.orm.hibernate4.SpringSessionContext.currentSession(SpringSessionContext.java:97)
at org.hibernate.internal.SessionFactoryImpl.getCurrentSession(SessionFactoryImpl.java:980)
at com.heavyweight.lexaholic.dao.hibernate.HibernateDAO.getSession(HibernateDAO.java:86)
at com.heavyweight.lexaholic.dao.hibernate.HibernateDAO.create(HibernateDAO.java:59)
at com.heavyweight.lexaholic.dao.hibernate.lexicon.DictionaryEntryHibernateDAOTest.testCRD(DictionaryEntryHibernateDAOTest.java:52)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:601)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:31)
at org.junit.runners.BlockJUnit4ClassRunner.runNotIgnored(BlockJUnit4ClassRunner.java:79)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:71)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:49)
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.junit.runners.ParentRunner.run(ParentRunner.java:236)
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)
org.hibernate.HibernateException: No Session found for current thread
at org.springframework.orm.hibernate4.SpringSessionContext.currentSession(SpringSessionContext.java:97)
at org.hibernate.internal.SessionFactoryImpl.getCurrentSession(SessionFactoryImpl.java:980)
at com.heavyweight.lexaholic.dao.hibernate.HibernateDAO.getSession(HibernateDAO.java:86)
at com.heavyweight.lexaholic.dao.hibernate.HibernateDAO.commit(HibernateDAO.java:41)
at com.heavyweight.lexaholic.dao.hibernate.lexicon.DictionaryEntryHibernateDAOTest.tearDown(DictionaryEntryHibernateDAOTest.java:43)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:601)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:37)
at org.junit.runners.BlockJUnit4ClassRunner.runNotIgnored(BlockJUnit4ClassRunner.java:79)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:71)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:49)
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.junit.runners.ParentRunner.run(ParentRunner.java:236)
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)
Here's the Spring configuration:
<bean id="testDatabase" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName"><value>org.h2.Driver</value></property>
<property name="url"><value>jdbc:h2:mem:test;DB_CLOSE_DELAY=-1</value></property>
<property name="username" value="sa"/>
<property name="password" value=""/>
</bean>
<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="testDatabase"/>
</bean>
<bean id="testSessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="testDatabase" />
<property name="annotatedClasses">
<list>
<value>com.heavyweight.lexaholic.model.lexicon.CrossReference</value>
<value>com.heavyweight.lexaholic.model.lexicon.Dictionary</value>
<value>com.heavyweight.lexaholic.model.lexicon.DictionaryEntry</value>
</list>
</property>
<property name="hibernateProperties">
<value>
hibernate.dialect=org.hibernate.dialect.H2Dialect
hibernate.show_sql=false
hibernate.jdbc.batch_size=0
hibernate.hbm2ddl.auto=create-drop
hibernate.use_sql_comments=false
</value>
</property>
</bean>
<bean id="dictionaryEntryDAO" class="com.heavyweight.lexaholic.dao.hibernate.lexicon.DictionaryEntryHibernateDAO" init-method="init">
<property name="sessionFactory" ref="testSessionFactory" />
</bean>
Best Answer
There are two things you need to modify:
Firstly, you are using Hibernate for persistence, so you need to use HibernateTransactionManager instead of DataSourceTransactionManager.
Secondly, you are using Hibernate 4.x, so you need to configure current session context class like this:
For information, reference http://blog.springsource.org/2012/04/06/migrating-to-spring-3-1-and-hibernate-4-1/
I hope you pass it