2013-03-18 4 views
3

Я использовал Spring и Hibernate в течение многих лет, но это мой первый проект с использованием Spring 3 и Hibernate 4.Spring 3 с Hibernate 4 - отказ модульного тестирования с Нет сессии найден для текущего потока

я создал Модель класса такой:

@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 направлений в весеннем руководстве, я затем настроить мой DAO и впрыснуть в экземпляре org.springframework.orm.hibernate4.LocalSessionFactoryBean. Тогда я называю getSession(), который:

/** 
    * Get the current session for a hibernate query 
    * @return the current session 
    */ 
    protected Session getSession(){ 
    return sessionFactory.getCurrentSession(); 
    } 

Я затем запустить мое модульное тестирование, впрыснуть в моей сессии заводе и запустить этот метод:

object = (T) getSession().save(object); 

Каких броски:

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) 

Вот конфигурация пружины:

<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> 
+0

конфигурации Spring? – madth3

ответ

1

Я думаю, что ваш тест может отсутствовать аннотацией TransactionConfiguration. Попробуйте следующее -

@TransactionConfiguration(transactionManager="txManager") 

В качестве альтернативы, вы можете изменить определение бина для менеджера транзакций следующим образом -

<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> 
<property name="dataSource" ref="testDatabase"/> 

К весне по умолчанию пытается найти боб 'TransactionManager'.

+0

Я переименовал txManager в transactionManager, но без радости. Не удалось найти файл jar с @TransactionConfiguration. – Thom

+0

Не могли бы вы разместить свой тестовый класс? – Sashi

4

Есть две вещи, которые нужно изменить:

Во-первых, вы используете Hibernate для персистенции, так что вам нужно использовать HibernateTransactionManager вместо DataSourceTransactionManager.

<!-- Transaction Configuration For All Services (including Hibernate and MyBatis)--> 
<bean id="txManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager"> 
    <property name="sessionFactory" ref="sessionFactory" /> 
</bean> 

<!-- Transaction: enable annotation-driven transaction --> 
<!--Put @Transactional on service impl instead of service interface--> 
<tx:annotation-driven transaction-manager="txManager" proxy-target-class="true"/> 

Во-вторых, вы используете Hibernate 4.x, так что вам нужно настроить текущей сессии контекст класса так:

<property name="hibernateProperties"> 
     <props> 
      <prop key="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</prop> 
      <prop key="hibernate.current_session_context_class">org.springframework.orm.hibernate4.SpringSessionContext</prop> 

Для получения информации, ссылка http://blog.springsource.org/2012/04/06/migrating-to-spring-3-1-and-hibernate-4-1/

I надеюсь, вы передадите его

+0

просто добавьте, вы не сможете получить сеанс, если хотите использовать весенние транзакции, обратитесь к этой ссылке для получения более подробной информации http://stackoverflow.com/questions/18832889/spring-transactions-and-hibernate-current -session контекст-класс –

2

У меня была такая же проблема в моей junit test в приложении весны 3 с гибернацией 3.6.
Когда приложение работает на сервере приложений, сеансы управляются с помощью сеанса фильтра:

<filter> 
    <filter-name>hibernateFilter</filter-name> 
    <filter-class>org.springframework.orm.hibernate3.support.OpenSessionInViewFilter</filter-class> 
</filter> 

Но при запуске JUnit он не загружен, вы должны имитировать его в тесте.
Одним из решений, как предлагается, является использование @TransactionConfiguration или расширение AbstractTransactionalJUnit4SpringContextTests, но оно не работает, если у вас есть классы уровня обслуживания, аннотированные с помощью @Service @Transactional, и вы вызываете его несколько раз в своем тесте.

я решил следующим образом, в соответствии с this сообщения:

@RunWith(SpringJUnit4ClassRunner.class) 
@ContextConfiguration(locations = {"classpath:context.xml"}) 
public class JUnitTestBase extends AbstractJUnit4SpringContextTests { 
    @Autowired 
    protected Log logger; 

    @Autowired 
    protected SessionFactory sessionFactory; 

    protected FlushMode flushMode = FlushMode.MANUAL; 

    @Before 
    public void setUp() throws Exception { 
     Session session = getSession(this.sessionFactory); 
     TransactionSynchronizationManager.bindResource(sessionFactory,new SessionHolder(session)); 
     logger.debug("Hibernate session is bound"); 
    } 

    @After 
    public void tearDown() throws Exception { 
     SessionHolder sessionHolder = (SessionHolder) TransactionSynchronizationManager.unbindResource(sessionFactory); 
     closeSession(sessionHolder.getSession(), sessionFactory); 
     logger.debug("Hibernate session is closed"); 
    } 

    protected void closeSession(Session session, SessionFactory sessionFactory) { 
     SessionFactoryUtils.closeSession(session); 
    } 

    protected Session getSession(SessionFactory sessionFactory) throws DataAccessResourceFailureException { 
     Session session = SessionFactoryUtils.getSession(sessionFactory, true); 
     FlushMode flushMode = this.flushMode; 
     if (flushMode != null) { 
      session.setFlushMode(flushMode); 
     } 
     return session; 
    } 
} 
Смежные вопросы