11

私は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.* パッケージから Hibernate 4 の SessionFactory、TransacionManager などを使用することを除いて、同じ構成をコピーしました。ただし、「アクティブなトランザクションがないと保存は無効です」という例外が発生し始めました。少し検索した後、多くの人が問題に直面しているようで、何人かは使用しないことを提案しました

        <prop key="hibernate.current_session_context_class ">thread</prop>

プロパティとそれは機能しました。それは私にとってもうまくいきました。Springのセッション管理戦略に干渉するコンテキストセッションとスレッド戦略に関係があるという投稿から収集できるすべての小さな情報。しかし、具体的な答えを見つけることができる場所はどこにもありませんでした。
また、Hibernate4 ではなく Hibernate3 で機能したのはなぜですか。何が違い、何が変わったのですか?他のすべての構成は同じです。私は @Transactional を使用していませんが、古い学校の XML の方法を使用しています。

Hibernate3 と Hibernate4 のこの動作の違いについて、誰かが明確な説明を教えてくれますか?

4

1 に答える 1

10

Spring のバージョンによって異なりますが、Spring の使用中にそのプロパティをいじることは一般的に避ける必要があります (トランザクションに JTA を使用しない限り、これを構成する必要があります)。

Hibernate 3.1 の時点で、コンテキスト セッションと呼ばれるものがあり、そのために hibernate はCurrentSessionContextインターフェイスを提供します。これにはいくつかの実装があります (のthread略ですThreadLocalSessionContext)。SpringSessionContextSpring には、このインターフェースクラスの独自の実装があります。

Spring はデフォルトでプロパティを の Spring 実装にCurrentSessionContext設定します。これが別のもの (JTA 以外) に設定されている場合、Spring が休止状態セッション (したがってトランザクション) を管理する機能が壊れます。

現在、Spring の古いバージョン (Spring を hibernate を使用できるようにアップグレードしたと仮定します) では、hibernate 3 と組み合わせると、セッションの取得に関して他のトリックが含まれていました (古い 3.x バージョンの hibernate との後方互換性のため)。これにより、Spring はそのプロパティの値にあまり依存しなくなりました。(Spring は のプロキシを作成し、SessionFactory基本的にメソッドをインターセプトしgetSessionてセッションを管理できるようにしました)。

于 2013-11-10T20:09:08.770 に答える