SpringとHibernate3を使用したアプリケーションが本番環境で正常に実行されています。以下は、SpringのapplicationContext.xmlのセッションファクトリの設定です。
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="mappingDirectoryLocations">
<list>
<value>classpath:/hibernate</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect
</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.format_sql">true</prop>
<prop key="hibernate.use_sql_comments">true</prop>
<prop key="hibernate.max_fetch_depth">2</prop>
<prop key="hibernate.autocommit">false</prop>
<prop key="hibernate.current_session_context_class ">thread</prop>
<prop key="hibernate.generate_statistics">true</prop>
<prop key="hibernate.jdbc.batch_size">20</prop>
</props>
</property>
</bean>
<bean id="txManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<!-- the transactional advice (what 'happens'; see the <aop:advisor/> bean
below) -->
<tx:advice id="txAdvice" transaction-manager="txManager">
<!-- the transactional semantics... -->
<tx:attributes>
<tx:method name="*" propagation="REQUIRED" />
<tx:method name="get*" propagation="SUPPORTS" read-only="true" />
<tx:method name="count*" propagation="SUPPORTS" read-only="true" />
<tx:method name="validate*" propagation="SUPPORTS"
read-only="true" />
<tx:method name="find*" propagation="SUPPORTS" read-only="true" />
<tx:method name="login" propagation="SUPPORTS" read-only="true" />
</tx:attributes>
</tx:advice>
<!-- ensure that the above transactional advice runs for any execution of
an operation defined by the service interfaces -->
<aop:config>
<aop:pointcut id="projectServiceOperation"
expression="execution(* com.service.project.IProjectService.*(..))" />
<aop:advisor advice-ref="txAdvice" pointcut-ref="projectServiceOperation" />
</aop:config>
本番環境では正常に動作しています。
現在、別のプロジェクトのために、Hibernate4に移行しています。 org.springframework.orm.hibernate4。*パッケージからHibernate4のSessionFactory、TransacionManagerなどを使用することを除いて、同じ構成をコピーしました。ただし、「アクティブなトランザクションがないと保存は無効です」という例外が発生し始めました。少し検索した後、多くの人が問題に直面しているようで、何人かの人は使用しないことを提案しました
<prop key="hibernate.current_session_context_class ">thread</prop>
プロパティとそれは働いた。それは私にとってもうまくいきました。投稿から収集できたすべての小さな情報は、コンテキストセッションと、Springのセッション管理戦略に干渉するスレッド戦略と関係があるというものです。しかし、具体的な答えを見つけることができた場所はありません。
また、なぜそれがHibernate4ではなくHibernate3で機能したのですか。違いは何ですか?何が変わったのですか?他のすべての構成は同じです。私は@Transactionalを使用していませんが、古い学校のXMLの方法を使用しています。
Hibernate3とHibernate4のこの動作の違いについて、誰かが私に明確な説明を教えてもらえますか?
これはSpringのバージョンによって異なりますが、一般に、Springを使用している間はそのプロパティをいじり回さないようにする必要があります(トランザクションにJTAを使用しない限り、これを構成する必要があります)。
Hibernate 3.1の時点で、コンテキストセッションと呼ばれるものがあり、そのためにhibernateはCurrentSessionContext
インターフェイスを提供します。これにはいくつかの実装があります(そしてthread
はThreadLocalSessionContext
の略です)。 Springには、このインターフェースの独自の実装SpringSessionContext
クラスがあります。
SpringはデフォルトでプロパティをCurrentSessionContext
のSprings実装に設定します。これが他の何か(JTA以外)に設定されている場合、これは休止状態のセッション(したがってトランザクション)を管理するSpringsの機能を破壊します。
現在、古いバージョンのSpring(および、Hibernateを使用できるようにSpringもアップグレードしたと思います)とhibernate 3を組み合わせると、セッションの取得に関して他のトリックが発生しました(古い3.xバージョンのHibernateとの下位互換性のため)。これにより、Springはそのプロパティの値にあまり依存しなくなりました。 (SpringはSessionFactory
のプロキシを作成し、基本的にgetSession
メソッドをインターセプトしてセッションを管理できるようにしました)。