テストケースで現在の休止状態セッションにアクセスしようとすると、次のエラーが発生します。
org.hibernate.HibernateException:スレッドにバインドされたHibernateセッションがありません。構成では、org.hibernate.implのorg.springframework.orm.hibernate3.SpringSessionContext.currentSession(SpringSessionContext.Java:63)で非トランザクションセッションを作成できません。 .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>
間違っています。これは、セッション管理コードでコードを埋めるだけです。
まず、コンテキストにトランザクション管理Beanを追加します。
<bean id="transactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
2つ目は、AbstractTransactionalJUnit4SpringContextTestsを拡張することです。
public class BaseDALTest
extends AbstractTransactionalJUnit4SpringContextTests{
3番目に、テストクラスに注釈を付けます
@TransactionConfiguration
@Transactional
トランザクションの境界が正しい場合(DAOまたはサービスを囲む)、完了します。
(テスト内であっても)コードの周りにセッションとトランザクション処理コードを散在させるのは良くありません。
Springのドキュメントを参照してください。テストに関する章全体とトランザクション管理に関するセクションがあります。
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);
}
});
上記のSpring構成では、コーディングするだけで十分です
_Session session = sessionFactory.getCurrentSession();
_
テストするメソッドとクラスで。セッション管理は、後でrealアプリケーションのHibernate/Spring構成で行われるように、Hibernate/Spring/JUnitテスト構成によって行われます。
これは私のテストでどのように機能したかです。最終的なWebアプリケーションでは、現在のWebリクエストに関連付けられたHibernateセッションが自動的に存在するため、テストではsessionFactory.openSession()
呼び出しはありません。
ええと。
セッションセッション=
sessionFactory.openSession();
Session session = sessionFactory.getCurrentSession();
おっとっと。
(これは間違っていたため編集され、賛成投票されました)。
春はhibernate.current_session_context_class=thread
プロパティ(使用しない)と説明されているように、HibernateのSessionFactory
を独自のトランザクションバージョンでラップします here
これに対する解決策は、プロパティを設定することです
<property name="exposeTransactionAwareSessionFactory"><value>false</value></property>
セッションファクトリBean構成