Spring / Hibernate / JUnit - сессия Hibernate не связана с потоком - PullRequest
19 голосов
/ 09 апреля 2009

Я пытаюсь получить доступ к текущему сеансу гибернации в тестовом примере и получаю следующую ошибку:

org.hibernate.HibernateException: нет Hibernate Session привязан к потоку, и конфигурация не позволяет создавать нетранзакционного здесь на org.springframework.orm.hibernate3.SpringSessionContext.currentSession (SpringSessionContext.java:63) в org.hibernate.impl.SessionFactoryImpl.getCurrentSession (SessionFactoryImpl.java:574)

Я явно пропустил какую-то настройку, но не уверен, что.

Любая помощь будет принята с благодарностью. Это мой первый трек в Hibernate / Spring и т. Д., И кривая обучения, конечно, крутая!

Код следует:

Класс обидчика:

public class DbUnitUtil extends BaseDALTest {
    @Test
    public void exportDtd() throws Exception
    {

        Session session = sessionFactory.getCurrentSession();

        session.beginTransaction();
        Connection hsqldbConnection = session.connection(); 

        IDatabaseConnection connection = new DatabaseConnection(hsqldbConnection);

        // write DTD file
        FlatDtdDataSet.write(connection.createDataSet(), new FileOutputStream("test.dtd"));
    }
}

Базовый класс:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations={"classpath:applicationContext.xml"})
public class BaseDALTest extends AbstractJUnit4SpringContextTests {
    public BaseDALTest()
    {
        super();
    }
        @Resource
        protected SessionFactory sessionFactory;
}

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"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName">
            <value>org.hsqldb.jdbcDriver</value>
        </property>
        <property name="url">
            <value>jdbc:hsqldb:mem:sample</value>
        </property>
        <property name="username">
            <value>sa</value>
        </property>
        <property name="password">
            <value></value>
        </property>
    </bean>

    <bean id="sessionFactory" class="com.foo.spring.AutoAnnotationSessionFactoryBean">
        <property name="dataSource" ref="dataSource" />
        <property name="entityPackages">
            <list>
                <value>com.sample.model</value>
            </list>
        </property>
        <property name="schemaUpdate">
            <value>true</value>
        </property>
        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.dialect">org.hibernate.dialect.HSQLDialect
                </prop>
                <prop key="hibernate.show_sql">true</prop>
            </props>
        </property>
    </bean>
</beans>

Ответы [ 5 ]

31 голосов
/ 18 июля 2009

Неправильно, это просто заполнит ваш код кодом управления сеансом.

Сначала добавьте bean-компонент управления транзакциями в вашем контексте:

    <bean id="transactionManager" 
          class="org.springframework.orm.hibernate3.HibernateTransactionManager">
        <property name="sessionFactory" ref="sessionFactory"/>
    </bean>

Второе, расширение AbstractTransactionalJUnit4SpringContextTests

    public class BaseDALTest 
           extends AbstractTransactionalJUnit4SpringContextTests{

В-третьих, комментируйте свой тестовый класс с помощью

    @TransactionConfiguration
    @Transactional

Если ваша разграничение транзакций правильное (окружает ваш dao или сервис), вам нужно сделать.

Неприлично разбрасывать код обработки сеансов и транзакций по всему коду (даже внутри ваших тестов).

5 голосов
/ 15 июня 2010

Пожалуйста, обратитесь к документации Spring. Существует целая глава по тестированию и раздел по управлению транзакциями:

http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/testing.html#testing-tx

Мне удалось расширить AbstractTransactionalJUnit4SpringContextTests, но есть обходной путь:

TransactionTemplate transactionTemplate = new TransactionTemplate(transactionManager);
transactionTemplate.execute(new TransactionCallbackWithoutResult() {
    @Override
    protected void doInTransactionWithoutResult(TransactionStatus status) {
        // DAO has access to the session through sessionFactory.getCurrentSession()
        myDao.findSomething(id);
    }
});
2 голосов
/ 26 апреля 2010

При вышеуказанной конфигурации Spring должно быть достаточно кодировать

Session session = sessionFactory.getCurrentSession();

в вашем методе и классе для тестирования. Управление сеансом осуществляется с помощью тестовой конфигурации Hibernate / Spring / JUnit, как это делается позже в конфигурации Hibernate / Spring в приложении real .

Вот как это сработало для моих тестов. В конечном веб-приложении автоматически будет сеанс Hibernate, связанный с текущим веб-запросом, и поэтому при тестировании не должно быть вызова sessionFactory.openSession().

0 голосов
/ 24 июня 2012

Spring игнорирует свойство hibernate.current_session_context_class=thread (, которое вы не используете ) и упаковывает SessionFactory Hibernate в собственную транзакционную версию, как объяснено здесь

Решением этой проблемы является установка свойства

<property name="exposeTransactionAwareSessionFactory"><value>false</value></property>

в конфигурации фабричного компонента сеанса

0 голосов
/ 09 апреля 2009

Duh.

Сеанс сессии = sessionFactory.openSession ();

Session session = sessionFactory.getCurrentSession();

Упс.

(Отредактировано, поскольку это было неправильно, и за него проголосовали).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...