【问题标题】:JPA entity persist not saving to DBJPA实体坚持不保存到数据库
【发布时间】:2016-03-09 01:23:32
【问题描述】:

编辑 所以,我从 Glassfish 切换到 Wildfly,并使用 EclipseLink 2.5。当我切换时,此代码停止工作,出现以下问题。由于某种原因,实体管理器是使用资源本地事务创建的。

我尝试了很多东西,但是当我切换到 Hibernate EM 时,一切正常。 结束编辑

我正在使用 Wildfly 10 和 Eclipselink JPA 让一个简单的无状态 EJB 将记录保存到数据库。方法在这里:

这个bean被标记为@Stateless

@POST
@Override
@Consumes({"application/xml", "application/json"})
public void create(Actor entity) {
    L.info("Creating {}", entity);
    super.create(entity);
    L.info("Created");
}

这里是抽象父类的方法:

public void create(T entity) {
    //getEntityManager().getTransaction().begin();
    getEntityManager().persist(entity);
    //getEntityManager().flush();
    //getEntityManager().getTransaction().commit();
}

如果我取消注释事务代码,它可以工作。

如果我添加事务注释,它不起作用。

这样不行。

为什么?我虽然 EJB 得到了容器管理的事务,并且这应该是自动提交的。这是我的持久性单元定义:

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.1" xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">
  <persistence-unit name="net.mikeski_auth_war_0.1.0-SNAPSHOTPU" transaction-type="JTA">
    <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
    <jta-data-source>java:jboss/datasources/PostgresqlDS</jta-data-source>
    <class>entities.Actor</class>
    <exclude-unlisted-classes>true</exclude-unlisted-classes>
    <properties>
      <property name="eclipselink.weaving" value="false"/>
      <property name="eclipselink.weaving.fetchgroups" value="false"/>
      <property name="javax.persistence.schema-generation.database.action" value="create"/>
    </properties>
  </persistence-unit>
</persistence>

我知道我的实体很好,因为如果我将一些添加到数据库中,则查找方法会起作用,如果我得到正确的事务,则插入会起作用。我错过了什么?

【问题讨论】:

  • 尝试将其标记为@Transactional
  • 你能贴出事务注释的应用上下文文件吗
  • 不起作用。我在抽象类的方法和实现方法上都试过了,还有类上的@TransactionManagement(TransactionManagementType.CONTAINER)
  • @Sanj - 不是 spring,只是 jpa
  • 看看 getEntityManager().joinTransaction() 是否有帮助。你也可以发布 getEntityManager() 源

标签: java jpa


【解决方案1】:

我希望您将对象传递给Stateless EJB,即使该EJB 只是为您调用em.persist。在这里,您正在混合功能,您正在让 REST 完成 EJB 的工作,并且您(和我)可能还没有完全理解一些事情。此外,service layer stateless ejb 里面大概还有其他功能,所以肯定不是浪费。

@Inject ActorService actorService;

@POST
@Consumes({"application/xml", "application/json"})
public void create(Actor entity) {
    L.info("Creating {}", entity);
    actorService.create(entity);
    L.info("Created");
}

并且,大概:

@Stateless
public class ActorService {
    @Inject private EntityManager em;

    public create(Actor actor) {
        em.persist(actor);
    }
    .. the rest of the actor service layer
}

我认为了解预期的做事方式比了解异常不正常的原因更重要。

希望这会有所帮助。

【讨论】:

  • 我正在使用这个设置,因为这是从实体生成 REST 服务的 Netbeans 模式。他们使用 @PersistenceContext 注释来创建 EM。在这种情况下,我将如何构造 EntityManager 以使其可用?
  • 嗨 Mikeb,我想说继续在你的无状态 ejb 中使用 @PersistenceContext。另外,是的,我通常使用一个 Resources 实用程序类来生成用于注入的 PersistenceContext,就像在所有 Wildfly samples 中所做的那样。另外,我认为hibernate比EclipseLink成熟得多。
【解决方案2】:

我认为在标有@Stateless 的bean 类中注入entityManager 应该可以。

如果您在其他类(父类)中获得entitymanager,请尝试从 entityManagerFactory 获取它,而不是直接注入它。您是否已经在超类中这样做了,或者您有用于注入 em 的吸气剂。

可能有java ee版本问题as discussed in an answer here 我认为这个答案应该会有所帮助。

因此,我同意 Nicholas 关于职责分离的意见。

【讨论】:

  • 好的,如果不是从@PersistenceContext 注解,我该如何创建实体管理器?
  • @mikeb 我的答案中的链接有相关代码。或者,您可以使用 Nicolas 在其示例代码中提到的方法,使用 Inject annotation
  • 我也试过了,还是不行。我切换到 Hibernate JPA,一切正常。我猜是 EclipseLink 和 Wildfly。
猜你喜欢
  • 1970-01-01
  • 2016-05-12
  • 2019-11-05
  • 2022-01-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多