【问题标题】:JPA EntityManager persist method doesn't save entity to db, but entity has id after persistJPA EntityManager 持久化方法不会将实体保存到数据库,但实体在持久化后具有 id
【发布时间】:2017-04-20 17:18:47
【问题描述】:

我正在尝试使用 jpa 将实体保存到数据库。这是我的实体:

import javax.persistence.*;

@Entity
public class Book {
    @Id
    @GeneratedValue
    private Long id;
    private String title;
    public Book() {
    }
    public Book(String title) {
        this.title = title;
    }
    public Long getId() {
        return id;
    }
    public String getTitle() {
        return title;
    }
    public void setTitle(String title) {
        this.title = title;
    }
}

这里是persistence.xml:

<persistence-unit name="bookUnit">
    <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
    <class>ee.jpa.Book</class>
    <properties>
        <property name="javax.persistence.schema-generation.database.action" value="drop-and-create"/>
        <property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver"/>
        <property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/Lessons"/>
        <property name="javax.persistence.jdbc.user" value="root"/>
        <property name="javax.persistence.jdbc.password" value="1"/>
    </properties>
</persistence-unit>

这是我的 EJB:

@Stateless
public class JpaBean {
    @PersistenceContext
    EntityManager entityManager;
    public long saveBook(Book book) {
        entityManager.persist(book);
        return book.getId();
    }
}

这是我的 servlet:

@WebServlet("/jpaExample")
public class ServletExample extends HttpServlet {
    @EJB
    JpaBean jpaBean;
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        Book book = new Book("servlet");
        long l = jpaBean.saveBook(book);
        resp.getWriter().write(l + " ");
    }
}

我已将 EclipseLink.jar 添加到我的项目和 TomcatEEDir/lib/ 目录中。一切都编译并运行,无一例外。每次运行 servlet 时我都会得到不同的数字,例如 1 2 3.... 等等。但是当我查看 db 时,那里什么也没有。没有表格,没有数据。我做错了什么?如何解决?我还尝试使用 java SE,为此我将 transaction-type="RESOURCE_LOCAL" 添加到持久性单元。并写了这样的代码:

public class MainExample {
public static void main(String[] args) {
    EntityManagerFactory emf = Persistence.createEntityManagerFactory("bookUnit");
    EntityManager em = emf.createEntityManager();
    Book book = new Book("main");
    EntityTransaction tx = em.getTransaction();
    tx.begin();
    em.persist(book);
    tx.commit();
    em.close();
    emf.close();
}
}

此代码完美运行并将数据保存到数据库。那么,我之前的代码有什么问题。为什么什么都没有保存到 DB?

编辑:如果使用 Hibernate,结果相同。

【问题讨论】:

  • 这似乎是事务的问题,如下所示。您可以尝试添加@TransactionAttribute(TransactionAttributeType.REQUIRED) 而不是@Transactional,因为后者AFAIK(我对EJB 不太熟悉)用于CDI bean。见:stackoverflow.com/questions/17838221/…
  • 我尝试添加 @Transactional 和 @TransactionAttribute(TransactionAttributeType.REQUIRED) 没有改变。
  • 嗨,你有没有找到解决这个问题的方法?

标签: java jpa servlets ejb jta


【解决方案1】:

我认为您应该调用 .flush() 以便保存它们。试试我认为它会起作用。也可以使用

@Transactional
public long saveBook(Book book) {
    entityManager.persist(book);
    entityManager.flush();
    return book.getId();
}

【讨论】:

  • 我试过写 entityManager.flush();但这没有帮助。据我了解,JTA 应该在启动 EJB 方法之前创建事务,并在之后提交它,所以所有更改都应该提交给 DB,而不需要额外的代码。
  • 顺便说一句,您的代码告诉我您拥有的这个数字 - 已保存书籍的 id 与持久性完全无关。即使你没有enetitymanager.persist,它也会被返回
  • 无论如何都尝试在您的方法上使用@Transactional
  • 我希望你已经在你的数据库中创建了这个表,对吧?
  • 我试过@Transaction,没有帮助,因为我知道 EJB 在没有这个注解的情况下是事务性的,我可以用它来进行事务性,例如servlet,但不是 EJB,默认情况下它是事务性的。是的,我已经在 db 中创建了表。当我运行 SE main 方法时,它创建了一行数据 id = 1 和 title = main。但是当我运行 EE 示例时,它不会将数据添加到数据库中。顺便说一句,当我运行 main 方法时,它还会在 db 中创建 SEQUENCE 表。
【解决方案2】:

在您的课程的帮助下,我完成了同样的项目。但是,我使用了 HibernatePersistenceProvider 和 WildFly 服务器。我遇到了以下问题并找到了一些解决方案。也许有什么可以帮助你。

  1. 当我添加一个 hibernate-core 依赖项时,我没有使用 scope=provided,但我应该有。

    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-core</artifactId>
        <version>5.2.17.Final</version>
        <scope>provided</scope>
    </dependency>
    
  2. persistence.xml 的位置是 WEB-INF->classes->META-INF。我的应用失败了,而我没有纠正这个。

这是我在 GitHub 上的项目的 a link

【讨论】:

    猜你喜欢
    • 2014-11-27
    • 2016-05-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-01
    • 1970-01-01
    相关资源
    最近更新 更多