0

我在网络和页面上进行了很多搜索,例如thisthis以及this主要建议使用 CMTTransactionFactory。但是我仍然无法使其工作(我想知道是不是因为我使用 LocalContainerEntityManagerFactoryBean 创建 EM 而不是通过 LocalSessionFactoryBean 创建 Hibernate 会话)

我的应用服务看起来像:

@Transactional(propagation=Propagation.REQUIRES_NEW)
public class FooServiceImpl implements FooService {
  @Inject
  private FooRepository fooRepo;

  public void doSomething() {
    Foo foo = fooRepo.findBySomething(...);
    foo.setBar(...);
    //fooRepo.flush();     // un-comment to do manual-flushing
  }
}

这是我的应用程序 ctx 中的代码段

<jee:jndi-lookup  id="dataSource" jndi-name="jdbc/fooDs" />

<bean id="transactionManager"
    class="org.springframework.transaction.jta.WebSphereUowTransactionManager" />

<bean id="emf" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
    <property name="jpaVendorAdapter">
        <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
            <property name="databasePlatform" value="org.hibernate.dialect.Oracle10gDialect" />
        </bean>
    </property>
    <property name="persistenceUnitName" value="foo" />
    <property name="dataSource" ref="dataSource" />
    <property name="packagesToScan" value="com.foo" />
    <!--
      <property name="persistenceXmlLocation" value="classpath:/META-INF/test-persistence.xml" />
     -->
    <property name="jpaPropertyMap">
        <map>
            <entry key="hibernate.dialect" value="org.hibernate.dialect.Oracle10gDialect" />
              <entry key="hibernate.transaction.manager_lookup_class" value="org.hibernate.transaction.WebSphereExtendedJTATransactionLookup" />
              <entry key="hibernate.transaction.factory_class" value="org.hibernate.transaction.CMTTransactionFactory"/>

            <entry key="hibernate.transaction.flush_before_completion"  value = "true" />
        </map>
    </property>
</bean>

我正在使用 Spring Data JPA,在检索到实体后,我更新了内容。如果我没有手动刷新存储库(这意味着 session/entityManager),它只会丢弃我的更改。

谁能给我一些提示,说明我在设置中错过了什么?使用 LocalContainerEntityManagerFactoryBean 有什么特别需要注意的吗?

我试图将 manager_lookup_class 的 jpaProperty 条目更改为, hibernate.transaction.jta.platform => org.hibernate.service.jta.platform.internal.WebSphereExtendedJtaPlatform但它没有帮助。

我也尝试使用org.hibernate.transaction.JTATransactionFactoryas transaction factory class,甚至删除transaction factory class. 这种变化似乎使 Hibernate 无法获取交易。当我手动刷新存储库时,它只是给我一个javax.persistence.TransactionRequiredException带有消息no transaction is in progress

我正在使用 Spring 3.1.2.RELEASE、JPA 和 Hibernate 4.1.6.Final、Websphere 8

有没有人使用上述组合并且有一个我可以遵循的工作配置?


编辑:我试图将 EntityManager 注入服务以避免使用 Spring Data JPA。症状是一样的:我必须显式调用 entityManager.flush() 让 Hibernate 拾取更新的实体。至少我们可以将 Spring Data 排除在外 :)

4

2 回答 2

0

我在其他论坛上提出了讨论。这是包含背后原因的链接。

http://forum.springsource.org/showthread.php?131051-Auto-Flush-not-working-for-Spring-3-1-LocalEntityManagerFactoryBean-Hibernate-4-JTA

这是由于,上述组合将设置事务类型为 RESOURCE_LOCAL 的实体管理器。这不适用于上述库版本组合(但在使用 Spring 2.5 + Hibernate 3 时有效)。

该问题的解决方法是将事务类型声明为 JTA(通过提供persistence.xml)。

Spring的后期版本提供了更好的解决方案,LocalEntityManagerFactoryBean提供了一个jtaDataSource属性(https://jira.springsource.org/browse/SPR-9883)

于 2012-12-05T07:29:03.297 回答
0

你的问题是这个条目。

<entry key="hibernate.transaction.factory_class" value="org.hibernate.transaction.CMTTransactionFactory"/>

删除它,事务完成后自动刷新工作。似乎添加了该条目后,您必须手动调用实体管理器刷新。

于 2014-06-26T15:55:22.127 回答