【问题标题】:EntityManager.merge() is not being committed (Wildfly, JPA, JTA)EntityManager.merge() 未提交(Wildfly、JPA、JTA)
【发布时间】:2017-02-15 19:05:36
【问题描述】:

我可以保存新数据,但不能进行更新。没有错误,只是没有提交更改的事务。我假设这与我设置交易的方式有关。我正在尝试一组相对较新的(对我而言)技术。以下是详细信息。

我正在使用以下工具/技术:

  • Wildfly 8 和 Java 7(这是我的托管服务使用的)
  • 注解,以最少的 XML 为目标
  • Struts 2.3(使用约定插件)
  • 春季 3.2
  • 休眠 4.3
  • JTA(使用容器管理事务 (CMT))
  • JPA 2(带有容器管理的持久性上下文)
  • EJB(我有一个运行 htmlunit 测试的远程客户端应用程序)
  • 已部署三个 WAR 文件和一个 EJB JAR 文件
  • 用于自动装配 EJB 的 SpringBeanAutowiringInterceptor(这里会不会出现事务未提交的错误?)

beanRefContext.xml(SpringBeanAutowiringInterceptor 需要)

<beans>
  <bean
    class="org.springframework.context.support.ClassPathXmlApplicationContext">
    <constructor-arg value="classpath:campaignerContext.xml" />
  </bean>
</beans>

campaignerContext.xml

<beans> 
  <context:component-scan base-package="..." />   
  <jee:jndi-lookup id="dataSource" jndi-name="jdbc/CampaignerDS"/>
  <tx:annotation-driven/> 
  <tx:jta-transaction-manager/>  
  <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
    <property name="persistenceUnitName" value="campaigner" />
  </bean>
  <bean id="ehCacheManager" class="net.sf.ehcache.CacheManager" factory-method="create">
    <constructor-arg type="java.net.URL" value="classpath:/campaigner_ehcache.xml"/>
  </bean> 
</beans>

persistence.xml

<persistence>
  <persistence-unit name="campaigner" transaction-type="JTA">
    <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
    <jta-data-source>java:/jdbc/CampaignerDS</jta-data-source>

    <class>....UserRegistration</class>
    ...

    <shared-cache-mode>ENABLE_SELECTIVE</shared-cache-mode>

    <properties>
      <property name="hibernate.transaction.jta.platform"  value="org.hibernate.service.jta.platform.internal.JBossAppServerJtaPlatform" />
     </properties>
  </persistence-unit>
</persistence>

SecurityServiceBean.java

@EnableTransactionManagement
@TransactionManagement(value = TransactionManagementType.CONTAINER)
@TransactionAttribute(value = TransactionAttributeType.REQUIRES_NEW)
@Stateless
@Interceptors(SpringBeanAutowiringInterceptor.class)
@DeclareRoles("Security Admin")
public class SecurityServiceBean extends AbstractCampaignerServiceImpl implements
    SecurityServiceLocal, SecurityServiceRemote
{
  @Override
  @PermitAll
  @Transactional(propagation = Propagation.REQUIRES_NEW)
  public UserRegistration confirmRegistration(
    String confirmationCode) throws ApplicationException
  {
      UserRegistration userRegistration = this.userRegistrationDAO
      .find(new UserRegistrationQuery(null, confirmationCode)).uniqueResult(); // Should be attached now

    ...
          userRegistration.setConfirmationDate(new Date());
          userRegistration.setState(State.CONFIRMED);
          userRegistration = this.userRegistrationDAO.saveOrUpdate(userRegistration);
    ...
  }
}

UserRegistrationDAO.java

@Override
public UserRegistration saveOrUpdate(
  UserRegistration obj) throws DAOException
{
  log.debug("[saveOrUpdate] isJoinedToTransaction? "
            + (this.em.isJoinedToTransaction() ? "Y " : "N"));

  try
  {
    if (obj.getId() == null)
    {
      this.em.persist(obj);

      log.debug("[saveOrUpdate] called persist()");

      return obj;
    }
    else
    {
      UserRegistration attached = this.em.merge(obj);

      log.debug("[saveOrUpdate] called merge()");

      return attached;
    }
  }
  catch (PersistenceException e)
  {
    throw new DAOException("[saveOrUpdate] obj=" + obj.toString() + ",msg=" + e.getMessage(), e);
  }
}

Wildfly 的standalone.xml 中是否有您需要查看或我应该设置的设置?

顺便说一句,这非常烦人和令人沮丧。这应该是一个简单的一次性设置,我可以做,然后在我继续创建我的网站时忘记,这应该是我大部分时间花费的地方。任何地方都缺乏全面的文档是惊人的。目前,开发已停止,直到解决此问题 /咆哮

更新

  • 我尝试切换到 XA 数据源,因为一些网站声称这是必要的,但那不起作用(不这么认为,但不得不尝试)。还尝试使用 dataSource 而不是像其他一些站点那样使用 persistenceUnitName 配置 emf。不开心。
  • 我尝试用 JpaTransactionManager 替换 transactionManager,但这只是导致了这个异常:A JTA EntityManager cannot use getTransaction()

【问题讨论】:

  • @EnableTransactionManagement 在这里几乎没用,它只适用于 @Configuration 带注释的类(并且您已经拥有 &lt;tx:annotation-driven /&gt;。当您使用 EJB 时,您还应该注意使用正确的@Transactional 注释,否则容器不会启动事务,也不会弹出,因为 EJB 不是 spring 管理的。
  • 感谢您的信息。当您说“正确的@Transactional 注释”时,您是什么意思?你说的是传播属性吗?
  • 不,您使用的是正确的,您不应该使用spring版本,而是使用EJB版本。
  • 哇!就是这样。非常感谢!
  • 我不明白的是,当您已经在使用带有默认事务支持的 EJB 时,为什么还需要 spring 事务?我可以理解没有 EJB 的 spring 事务的使用,但是如果您不使用 EJB tx 管理功能,为什么要使用 EJB?有没有人知道他在做什么?

标签: java spring hibernate jpa jta


【解决方案1】:

感谢 M. Deinum,答案是我使用了错误的 @Transactional。我应该一直在使用 javax.transaction.Transactional 但使用的是 Spring 。请注意,正确的看起来像“@Transactional(TxType.REQUIRES_NEW)”而不是“@Transactional(propagation = Propagation.REQUIRES_NEW)”

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-23
    • 1970-01-01
    • 1970-01-01
    • 2011-03-13
    • 1970-01-01
    • 2015-12-24
    相关资源
    最近更新 更多