Использование свойства current_session_context_class hibernate 3 hibernate 4
У меня есть приложение с работающими Spring и Hibernate3. Ниже приводится конфигурация фабрики сеансов в приложении SpringContext.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. мы скопировали поверх той же конфигурации, за исключением использования SessionFactory,TransacionManager и т. д. из пакета org.springframework.orm.hibernate4.* из Hierrnate 4. Однако он начал выдавать исключение, говорящее "Сохранение недействительно без активной транзакции". После небольшого поиска многие люди, похоже, столкнулись с проблемами, и несколько человек предложили не использовать
<prop key="hibernate.current_session_context_class ">thread</prop>
собственность и это сработало. Это также сработало для меня. Вся небольшая информация, которую я мог собрать из постов, касалась контекстных сессий и стратегии потоков, которая мешает стратегии управления сессиями Spring. Но нет, где я мог найти какой-либо конкретный ответ. Кроме того, почему это работает с Hibernate3, а не с Hibernate4. В чем разница и что изменилось? Все остальные конфигурации одинаковы. Я не использую @Transactional, а способ старой школы XML.
Can somebody point me to clear explaination for this behavioural difference in Hibernate3 and Hibernate4?
1 ответ
Это зависит от версии Spring, но в целом следует избегать возни с этим свойством во время использования Spring (если вы не используете JTA для транзакций, вам нужно настроить это).
В Hibernate 3.1 есть что-то, называемое контекстными сессиями, и для этого Hibernate предоставляет CurrentSessionContext
интерфейс. Есть несколько реализаций для этого (и thread
коротка для ThreadLocalSessionContext
). Spring имеет собственную реализацию этого интерфейса SpringSessionContext
учебный класс.
Spring по умолчанию устанавливает свойство для реализации Springs CurrentSessionContext
, когда это установлено на что-то другое (кроме JTA), это лишит возможности пружины управлять сеансом гибернации (и, следовательно, транзакцией).
Теперь в более старых версиях Spring (и я полагаю, что вы также обновили Spring, чтобы иметь возможность использовать hibernate) в сочетании с hibernate 3, были некоторые другие хитрости, связанные с получением сессии (из-за обратной совместимости со старыми 3.x версиями hibernate). Это сделало Spring менее зависимым от стоимости этого свойства. (Spring создал прокси для SessionFactory
и в основном перехватили getSession
метод, чтобы иметь возможность управлять сессией).