在 Hibernate 4 + Spring 4 + JTA 中查找使用 HQL 或会话过滤器查询的对象的问题
Issues with finding objects queried with HQL or session filter in Hibernate 4 + Spring 4 + JTA
我们最近在 Weblogic 10.3
上从 Hibernate 3.2.3、Spring 3.2.2 迁移到 Hibernate 4.3.11 和 Spring 4.2.1
现在在事务中创建休眠对象并将其添加到休眠对象的持久集合中,然后使用 HQL(使用 hibernateTemplate)或 Hibernate 的 "Query" 功能进行查询(在同一事务中并在结束之前)事务),Hibernate 无法找到添加的对象。这在升级前适用于 Hibernate 3 和 Spring 3,但现在失败了。
例如在伪代码中,假设我有一个库 class,其中包含以下 属性。
class Library{
private Collection<Books> books;
}
在交易中,我执行以下操作 -
...
Book book1 = new Book();
book1.setAuthor("Patrick Holt");
library.getBooks().add(book1);
后来在同一个事务中,Hibernate 的 "Query" 与过滤器一起使用来查找作者的书籍,就像这样
Session s = hibernateTemplate.getSessionFactory().getCurrentSession();
Query q = s.createFilter(library.getBooks(), "where this.author = :authorName");
q.setParameter("authorName", "Patrick Holt");
List l = q.list();
q.list() 在上面的例子中 returns 0 个结果。这将在升级前得到 return 1 个结果。升级后我得到 0 个结果。
我读到关于升级到 Hibernate 4 和 Spring 4 时 currentSessionContext 的一些变化,但我不确定需要改变什么才能使行为与升级前一样,而无需必须更改代码。
休眠对象在 hbm.xml 文件中定义,这是我对会话工厂的配置。
<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.OracleDialect</prop>
<prop key="hibernate.show_sql">false</prop>
<prop key="hibernate.cache.use_second_level_cache">true</prop>
<prop key="hibernate.cache.use_query_cache">true</prop>
<prop key="hibernate.cache.provider_class">net.sf.ehcache.hibernate.EhCacheProvider</prop>
<prop key="hibernate.cache.provider_configuration_file_resource_path">/WEB-INF/ehcache.xml</prop>
<prop key="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.SingletonEhCacheRegionFactory</prop>
<!--
Tried adding the following properties, but it didn't work either
<prop key="hibernate.transaction.jta.platform">org.hibernate.engine.transaction.jta.platform.internal.WeblogicJtaPlatform</prop>
<prop key="hibernate.transaction.factory_class">org.hibernate.engine.transaction.internal.jta.JtaTransactionFactory</prop>-->
</props>
</property>
<property name="dataSource" ref="dataSource"/>
<property name="mappingJarLocations">
<list>
<value>/WEB-INF/lib/app-1.0.jar</value>
</list>
</property>
</bean>
事务管理器定义:
<bean id="transactionManager" class="org.springframework.transaction.jta.WebLogicJtaTransactionManager"/>
数据源通过 jndi 可用。
关于我需要做什么来解决这个问题有什么想法吗?
我遇到的问题与 Spring Jira Issue SPR-13848 中描述的完全一样。据我了解,OpenSessionInViewFilter 似乎提前打开了一个请求范围的会话,并且与稍后启动的事务同步存在问题。
我无法摆脱我的 OSIV,因为它会对我的整个应用程序造成影响。
但是,我发现 hibernate 有一个 属性 可以完成类似的事情来防止延迟加载 -
<prop key="hibernate.enable_lazy_load_no_trans">true</prop>
这解决了问题。添加此 属性 允许我删除 OSIV,并且休眠的 AUTO 刷新模式现在在事务中按预期工作。我还使用了 CMTTransactionFactory。我所有的休眠属性:
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.Oracle10gDialect</prop>
<prop key="hibernate.show_sql">false</prop>
<prop key="hibernate.cache.use_second_level_cache">true</prop>
<prop key="hibernate.cache.use_query_cache">true</prop>
<prop key="hibernate.cache.provider_class">net.sf.ehcache.hibernate.EhCacheProvider</prop>
<prop key="hibernate.cache.provider_configuration_file_resource_path">/WEB-INF/ehcache.xml</prop>
<prop key="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.SingletonEhCacheRegionFactory</prop>
<prop key="hibernate.enable_lazy_load_no_trans">true</prop>
<prop key="hibernate.transaction.jta.platform">org.hibernate.engine.transaction.jta.platform.internal.WeblogicJtaPlatform</prop>
<prop key="hibernate.transaction.factory_class">org.hibernate.engine.transaction.internal.jta.CMTTransactionFactory</prop>
</props>
我们最近在 Weblogic 10.3
上从 Hibernate 3.2.3、Spring 3.2.2 迁移到 Hibernate 4.3.11 和 Spring 4.2.1现在在事务中创建休眠对象并将其添加到休眠对象的持久集合中,然后使用 HQL(使用 hibernateTemplate)或 Hibernate 的 "Query" 功能进行查询(在同一事务中并在结束之前)事务),Hibernate 无法找到添加的对象。这在升级前适用于 Hibernate 3 和 Spring 3,但现在失败了。
例如在伪代码中,假设我有一个库 class,其中包含以下 属性。
class Library{
private Collection<Books> books;
}
在交易中,我执行以下操作 -
...
Book book1 = new Book();
book1.setAuthor("Patrick Holt");
library.getBooks().add(book1);
后来在同一个事务中,Hibernate 的 "Query" 与过滤器一起使用来查找作者的书籍,就像这样
Session s = hibernateTemplate.getSessionFactory().getCurrentSession();
Query q = s.createFilter(library.getBooks(), "where this.author = :authorName");
q.setParameter("authorName", "Patrick Holt");
List l = q.list();
q.list() 在上面的例子中 returns 0 个结果。这将在升级前得到 return 1 个结果。升级后我得到 0 个结果。
我读到关于升级到 Hibernate 4 和 Spring 4 时 currentSessionContext 的一些变化,但我不确定需要改变什么才能使行为与升级前一样,而无需必须更改代码。
休眠对象在 hbm.xml 文件中定义,这是我对会话工厂的配置。
<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.OracleDialect</prop>
<prop key="hibernate.show_sql">false</prop>
<prop key="hibernate.cache.use_second_level_cache">true</prop>
<prop key="hibernate.cache.use_query_cache">true</prop>
<prop key="hibernate.cache.provider_class">net.sf.ehcache.hibernate.EhCacheProvider</prop>
<prop key="hibernate.cache.provider_configuration_file_resource_path">/WEB-INF/ehcache.xml</prop>
<prop key="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.SingletonEhCacheRegionFactory</prop>
<!--
Tried adding the following properties, but it didn't work either
<prop key="hibernate.transaction.jta.platform">org.hibernate.engine.transaction.jta.platform.internal.WeblogicJtaPlatform</prop>
<prop key="hibernate.transaction.factory_class">org.hibernate.engine.transaction.internal.jta.JtaTransactionFactory</prop>-->
</props>
</property>
<property name="dataSource" ref="dataSource"/>
<property name="mappingJarLocations">
<list>
<value>/WEB-INF/lib/app-1.0.jar</value>
</list>
</property>
</bean>
事务管理器定义:
<bean id="transactionManager" class="org.springframework.transaction.jta.WebLogicJtaTransactionManager"/>
数据源通过 jndi 可用。
关于我需要做什么来解决这个问题有什么想法吗?
我遇到的问题与 Spring Jira Issue SPR-13848 中描述的完全一样。据我了解,OpenSessionInViewFilter 似乎提前打开了一个请求范围的会话,并且与稍后启动的事务同步存在问题。
我无法摆脱我的 OSIV,因为它会对我的整个应用程序造成影响。 但是,我发现 hibernate 有一个 属性 可以完成类似的事情来防止延迟加载 -
<prop key="hibernate.enable_lazy_load_no_trans">true</prop>
这解决了问题。添加此 属性 允许我删除 OSIV,并且休眠的 AUTO 刷新模式现在在事务中按预期工作。我还使用了 CMTTransactionFactory。我所有的休眠属性:
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.Oracle10gDialect</prop>
<prop key="hibernate.show_sql">false</prop>
<prop key="hibernate.cache.use_second_level_cache">true</prop>
<prop key="hibernate.cache.use_query_cache">true</prop>
<prop key="hibernate.cache.provider_class">net.sf.ehcache.hibernate.EhCacheProvider</prop>
<prop key="hibernate.cache.provider_configuration_file_resource_path">/WEB-INF/ehcache.xml</prop>
<prop key="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.SingletonEhCacheRegionFactory</prop>
<prop key="hibernate.enable_lazy_load_no_trans">true</prop>
<prop key="hibernate.transaction.jta.platform">org.hibernate.engine.transaction.jta.platform.internal.WeblogicJtaPlatform</prop>
<prop key="hibernate.transaction.factory_class">org.hibernate.engine.transaction.internal.jta.CMTTransactionFactory</prop>
</props>