在 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>