【问题标题】:Servlet does not persist an EntityServlet 不持久化实体
【发布时间】:2015-04-08 10:41:19
【问题描述】:

我想做什么:

我刚开始使用 JPA,因此我想从不同的角度了解持久实体是如何工作的(应用程序管理的、容器管理的)。应用程序管理工作正常,但是我在使用 TestServlet 从 Web 应用程序中通过实体管理器持久化实体时遇到问题。

到目前为止我做了什么:

IDE:NetBeans 8.0.2 服务器:GlassFish 4.1 mysql 5.6 JPA 2.1:EclipseLink

  1. 我创建了一个 Web 应用程序项目。
  2. 我已经使用 NetBeans 向导从数据库中导入了实体。 由于某种原因,我无法从 jdbc/__default 导入它们。 我必须创建一个新的数据源。在这种情况下,它是 jdbc/__onlineshop

我只是想在 Servlet 中创建一个实体并将其保存在数据库中,以便在继续之前了解它是如何工作的,但显然我不太明白。

我已连接到数据库,我可以通过 Java 应用程序访问它,但不能使用 Web 容器中的 Servlet。

MySQL 驱动程序位于类路径 MAIN - Libraries 中。

不抛出异常。 Servlet 被调用,我可以在浏览器中看到它。但是通过 RequestDispatcher 的重定向也不起作用,浏览器 URL 停留在 web-jpa/test。

我的问题:

由于持久化不起作用,我的 Servlet 或 persistence.xml 有什么问题吗?

persistence.xml:

<?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="jpa-webPU" transaction-type="JTA">
 <jta-data-source>jdbc/__onlineshop</jta-data-source>
 <exclude-unlisted-classes>false</exclude-unlisted-classes>
 <properties/>
</persistence-unit>

TestServlet.java:

package jpa;

import java.io.IOException;
import javax.annotation.Resource;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.PersistenceUnit;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.transaction.UserTransaction;

@WebServlet("/test")
public class TestServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;


@PersistenceUnit
EntityManagerFactory emf;

@Resource
private UserTransaction ut;

@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
        throws ServletException, IOException {


    EntityManager em = emf.createEntityManager();

    Customer customer = new Customer();

    customer.setEmail("email@test.com");
    customer.setPassword("password");

    try 
    {
        ut.begin();
        em.persist(customer);
        ut.commit();

    } catch (Exception e) {

        try 
        {
            ut.rollback();

        } catch (Exception e1) 
        {
            e1.printStackTrace();
        }

        throw new ServletException(e.getMessage());

    }finally
    {
        em.close();
    }

    RequestDispatcher dispatcher = request.getRequestDispatcher    ("index.html");
    dispatcher.forward(request, response);

}
}

谢谢!

p.s.:感谢任何提示!

【问题讨论】:

  • 您混淆了重定向和转发。转发只是将处理请求的责任转移给另一个组件。它不能更改 URL。重定向(使用 HttpServletResponse.sendRedirect())向浏览器发送响应并告诉它转到另一个 URL。这可以改变 URL。
  • 你有什么问题?
  • 我已经编辑了帖子。基本问题是:我在 servlet 中持久化实体的方式有什么问题吗?我不明白为什么它不将实体保留在数据库中。
  • 如果它没有抛出任何异常,那么你的实体可能已经被持久化了。确保查看正确的数据库。也就是说,您不应该使用 servlet 中的 EM。委托给事务性 CDI bean 或无状态 EJB。使用声明式事务管理而不是那些可怕的 try/catch/commit/rollback 块。
  • 请转移到 EJB。这样,您无需手动获取实体管理器,也无需手动处理丑陋的用户事务和手动回滚。您所需要的只是 EJB 方法中的 em.persist(entity); 行。只需创建一个类,注释它@Stateless,添加一个@PersistenceContext private EntityManager em; 字段并添加处理它的公共方法。最后通过@Inject 将它注入到servlet 中,并让它依次调用一个这样的EJB 方法。就这样。单个无状态 EJB 方法调用透明地算作单个完整事务,包括回滚等等。

标签: jakarta-ee servlets jpa persistence entitymanager


【解决方案1】:

终于找到了解决办法:

try
{
  ut.begin();
  em.joinTransaction(); // this is necessary, the entitymanager needs to be called specifically
  em.persist(customer);
  ut.commit();
}

【讨论】:

    【解决方案2】:

    将文件放置在所示结构中。实体可以持久化。它对我有用

    【讨论】:

      猜你喜欢
      • 2013-04-06
      • 2014-11-27
      • 1970-01-01
      • 2020-02-13
      • 2012-10-12
      • 1970-01-01
      • 2015-11-15
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多