【问题标题】:creating and persisting entities from servlets从 servlet 创建和持久化实体
【发布时间】:2013-04-06 17:56:01
【问题描述】:

我正在尝试在 servlet 和调用时创建和持久化实体

public void create(T entity) { getEntityManager().persist(entity); }

来自 servlet,这是在 AbstractFacade 中为所有 EJB 生成的方法,我得到 EJBException。现在,我正在考虑使用此方法在无状态 EJB 中创建和持久化实体并从 servlet 调用它

public boolean createUser(JavaBean jb){}.

这是个好主意吗?创建和持久化实体(即创建用户帐户)的最佳方式是什么?

感谢您的帮助。

这就是问题所在。 我想在数据库中的两个表中创建记录,成员详细信息和地址。他们是一对一的关系。该关系尚未由数据库中的外键强制执行。两个表都有对应的实体类,实体类 Address 有 Embeddable 类 AddressPK 表示其复合主键。一对一关系仅在实体中由地址中的@ JoinColumn(name = "MEMBER_ID") 和成员详细信息中的@OneToOne(mappedBy = "memberId", cascade = CascadeType.ALL) 强制执行。现在,我从 JSP 表单中获取数据,并在另一个 JSP 中设置了 JavaBean。 Servlet 创建实体并调用注入的 EJB 来持久化它们,如下所示:

        //get MemberBean from session object
    MemberBean member = (MemberBean) request.getSession().getAttribute("user");
    //create relevant entities and set attributes of entity classes
    MemberDetails aMember = new MemberDetails("M3", firstName, middleName, lastName, dob, phoneNo,
            member.getEmail(), gender, industryPosition, "Basic", musicInterests);
    AddressPK addressId = new AddressPK(houseNo, postCode);
    Address anAddress = new Address(addressId, street, county, town, country, aMember);
    aMember.setAddress(anAddress);


    if (memberDetails.find(aMember.getMemberId()) == null) {
        //address.create(anAddress);

        memberDetails.create(aMember);

    }
    else
    { System.out.println("User M3 Exists");}

    //tests
    memberDetails.displayMembers();

    RequestDispatcher disp = request.getRequestDispatcher("WEB-INF/jsp/accounttype.jsp");
    disp.forward(request, response);

我创建了普通的 Java 应用程序客户端,并使用显式事务插入了这些详细信息,并且成功了。当注释掉地址并只保留成员详细信息时,它也可以工作。

这是我尝试将 MemberDetails 和 Address 一起插入时遇到的异常。

警告:EJB5184:在调用 EJB MemberDetailsFacade 期间发生系统异常,方法:public void beans.MemberDetailsFacade.create(entities.MemberDetails) 警告:javax.ejb.EJBException 在 com.sun.ejb.containers.BaseContainer.processSystemException(BaseContainer.java:5215) 在 com.sun.ejb.containers.BaseContainer.completeNewTx(BaseContainer.java:5113) 在 com.sun.ejb.containers.BaseContainer.postInvokeTx(BaseContainer.java:4901) 在 com.sun.ejb.containers.BaseContainer.postInvoke(BaseContainer.java:2045) 在 com.sun.ejb.containers.BaseContainer.postInvoke(BaseContainer.java:1994) 在 com.sun.ejb.containers.EJBLocalObjectInvocationHandler.invoke(EJBLocalObjectInvocationHandler.java:222) 在 com.sun.ejb.containers.EJBLocalObjectInvocationHandlerDelegate.invoke(EJBLocalObjectInvocationHandlerDelegate.java:89) 在 sun.proxy.$Proxy233.create(未知来源) 在 servlets.NewAccountFormHandler.doPost(NewAccountFormHandler.java:137) 在 javax.servlet.http.HttpServlet.service(HttpServlet.java:688) 在 javax.servlet.http.HttpServlet.service(HttpServlet.java:770) 在 org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1550) 在 org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:281) 在 org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175) 在 org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:655) 在 org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:595) 在 org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:161) 在 org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:331) 在 org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:231) 在 com.sun.enterprise.v3.services.impl.ContainerMapper$AdapterCallable.call(ContainerMapper.java:317) 在 com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:195) 在 com.sun.grizzly.http.ProcessorTask.invokeAdapter(ProcessorTask.java:860) 在 com.sun.grizzly.http.ProcessorTask.doProcess(ProcessorTask.java:757) 在 com.sun.grizzly.http.ProcessorTask.process(ProcessorTask.java:1056) 在 com.sun.grizzly.http.DefaultProtocolFilter.execute(DefaultProtocolFilter.java:229) 在 com.sun.grizzly.DefaultProtocolChain.executeProtocolFilter(DefaultProtocolChain.java:137) 在 com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:104) 在 com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:90) 在 com.sun.grizzly.http.HttpProtocolChain.execute(HttpProtocolChain.java:79) 在 com.sun.grizzly.ProtocolChainContextTask.doCall(ProtocolChainContextTask.java:54) 在 com.sun.grizzly.SelectionKeyContextTask.call(SelectionKeyContextTask.java:59) 在 com.sun.grizzly.ContextTask.run(ContextTask.java:71) 在 com.sun.grizzly.util.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:532) 在 com.sun.grizzly.util.AbstractThreadPool$Worker.run(AbstractThreadPool.java:513) 在 java.lang.Thread.run(Thread.java:722) 原因:javax.validation.UnexpectedTypeException:HV000030:找不到类型的验证器:entities.MemberDetails。 ...

【问题讨论】:

  • 你到底在问什么?如果您想了解为什么会收到 EJBException,您应该向我们展示异常的堆栈跟踪和相关代码。
  • 当然没有必要定义只保留实体的 EJB。向我们展示有关错误的更多详细信息
  • 您是否将实体声明为 EJB ?
  • 我在上面添加了完整的描述,包括异常。我没有将实体声明为 EJB。

标签: jakarta-ee servlets persistence entity ejb-3.1


【解决方案1】:

不清楚您要做什么,但使用封装实体管理器的无状态 EJB 确实是最佳实践。

这样的 EJB 可以被注入到 Servlet 中,而不必担心线程安全问题。

如果您直接在 Servlet 中使用实体管理器,则必须注意此类问题(实体管理器不是线程安全的,所有请求只有 1 个 Servlet 实例。您还必须手动管理事务。

有了一个简单轻量的 EJB bean,所有的复杂性都消失了。

【讨论】:

  • 是的,我有一个封装在 EJB 中的实体管理器,我调用 create() 方法,它是抽象类中的方法,实现为来自注入 EJB 的 servlet 的 EJB。
猜你喜欢
  • 2015-04-08
  • 2012-01-15
  • 2019-10-20
  • 1970-01-01
  • 2015-11-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多