Java 无法保留分离的对象

Java 无法保留分离的对象,java,postgresql,netbeans,Java,Postgresql,Netbeans,我正在使用一个连接到postresql数据库的java企业应用程序,在日志文件中出现此错误 javax.ejb.EJBException at com.sun.ejb.containers.BaseContainer.processSystemException(BaseContainer.java:3894) at com.sun.ejb.containers.BaseContainer.completeNewTx(BaseContainer.java:3794) at com.sun.ejb

我正在使用一个连接到postresql数据库的java企业应用程序,在日志文件中出现此错误

javax.ejb.EJBException
at com.sun.ejb.containers.BaseContainer.processSystemException(BaseContainer.java:3894)
at com.sun.ejb.containers.BaseContainer.completeNewTx(BaseContainer.java:3794)
at com.sun.ejb.containers.BaseContainer.postInvokeTx(BaseContainer.java:3596)
at com.sun.ejb.containers.BaseContainer.postInvoke(BaseContainer.java:1379)
at com.sun.ejb.containers.BaseContainer.postInvoke(BaseContainer.java:1316)
at com.sun.ejb.containers.EJBLocalObjectInvocationHandler.invoke(EJBLocalObjectInvocationHandler.java:205)
at com.sun.ejb.containers.EJBLocalObjectInvocationHandlerDelegate.invoke(EJBLocalObjectInvocationHandlerDelegate.java:127)
at $Proxy120.create(Unknown Source)
at com.mirodinero.web.servlets.setMisDatos.processRequest(setMisDatos.java:111)
at com.mirodinero.web.servlets.setMisDatos.doGet(setMisDatos.java:140)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:734)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:847)
at org.apache.catalina.core.ApplicationFilterChain.servletService(ApplicationFilterChain.java:427)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:315)
at org.apache.catalina.core.StandardContextValve.invokeInternal(StandardContextValve.java:287)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:218)
at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:648)
at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:593)
at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:94)
at com.sun.enterprise.web.PESessionLockingStandardPipeline.invoke(PESessionLockingStandardPipeline.java:98)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:222)
at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:648)
at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:593)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:587)
at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:1096)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:166)
at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:648)
at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:593)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:587)
at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:1096)
at org.apache.coyote.tomcat5.CoyoteAdapter.service(CoyoteAdapter.java:288)
at com.sun.enterprise.web.connector.grizzly.DefaultProcessorTask.invokeAdapter(DefaultProcessorTask.java:647)
at com.sun.enterprise.web.connector.grizzly.DefaultProcessorTask.doProcess(DefaultProcessorTask.java:579)
at com.sun.enterprise.web.connector.grizzly.DefaultProcessorTask.process(DefaultProcessorTask.java:831)
at com.sun.enterprise.web.connector.grizzly.DefaultReadTask.executeProcessorTask(DefaultReadTask.java:341)
at com.sun.enterprise.web.connector.grizzly.DefaultReadTask.doTask(DefaultReadTask.java:263)
at com.sun.enterprise.web.connector.grizzly.DefaultReadTask.doTask(DefaultReadTask.java:214)
at com.sun.enterprise.web.connector.grizzly.TaskBase.run(TaskBase.java:265)
at com.sun.enterprise.web.connector.grizzly.ssl.SSLWorkerThread.run(SSLWorkerThread.java:106)
原因:javax.persistence.EntityExistsException: 异常描述:无法持久化分离的对象[com.mirodinero.entidad.datosuario[idUsuario=Miguel LLorente]]。 Class>com.mirodinero.entidad.datosuario主键>[Miguel LLorente] 位于oracle.toplink.essentials.internal.ejb.cmp3.base.EntityManagerImpl.persist(EntityManagerImpl.java:224) 位于com.sun.enterprise.util.EntityManagerRapper.persist(EntityManagerRapper.java:440) 位于com.mirodinero.sesionBean.datosuarioacade.create(datosuarioacade.java:30) 在sun.reflect.NativeMethodAccessorImpl.invoke0(本机方法)处 位于sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) 在sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)中 位于java.lang.reflect.Method.invoke(Method.java:597) 位于com.sun.enterprise.security.application.EJBSecurityManager.runMethod(EJBSecurityManager.java:1011) 位于com.sun.enterprise.security.SecurityUtil.invoke(SecurityUtil.java:175) 在com.sun.ejb.containers.BaseContainer.invokeTargetBeanMethod(BaseContainer.java:2920)上 在com.sun.ejb.containers.BaseContainer.intercept(BaseContainer.java:4011)上 在com.sun.ejb.containers.ejblocationHandler.invoke(ejblocationHandler.java:197) ... 33多 导致原因:异常[TOPLINK-7231](Oracle TOPLINK Essentials-2.1(构建b60e fcs(12/23/2008)):Oracle.TOPLINK.Essentials.exceptions.ValidationException 异常描述:无法持久化分离的对象[com.mirodinero.entidad.datosuario[idUsuario=Miguel LLorente]]。 Class>com.mirodinero.entidad.datosuario主键>[Miguel LLorente] 位于oracle.toplink.essentials.Exception.ValidationException.CannotPersistingObject(ValidationException.java:2171) 位于oracle.toplink.essentials.internal.sessions.UnitOfWorkImpl.registerNotRegisteredNewObjectForPersist(UnitOfWorkImpl.java:3257) 位于oracle.toplink.essentials.internal.ejb.cmp3.base.RepeatableWriteUnitOfWork.registerNotRegisteredNewObjectForPersist(RepeatableWriteUnitOfWork.java:432) 位于oracle.toplink.essentials.internal.sessions.UnitOfWorkImpl.registerNewObjectForPersist(UnitOfWorkImpl.java:3226) 位于oracle.toplink.essentials.internal.ejb.cmp3.base.EntityManagerImpl.persist(EntityManagerImpl.java:221) ... 44多

这是:

javax.persistence.NoResultException: getSingleResult() did not retrieve any entities.
at oracle.toplink.essentials.internal.ejb.cmp3.EJBQueryImpl.throwNoResultException(EJBQueryImpl.java:274)
at oracle.toplink.essentials.internal.ejb.cmp3.base.EJBQueryImpl.getSingleResult(EJBQueryImpl.java:513)
at com.mirodinero.sesionBean.DatosUsuarioFacade.findById(DatosUsuarioFacade.java:57)
at sun.reflect.GeneratedMethodAccessor560.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at com.sun.enterprise.security.application.EJBSecurityManager.runMethod(EJBSecurityManager.java:1011)
at com.sun.enterprise.security.SecurityUtil.invoke(SecurityUtil.java:175)
at com.sun.ejb.containers.BaseContainer.invokeTargetBeanMethod(BaseContainer.java:2920)
at com.sun.ejb.containers.BaseContainer.intercept(BaseContainer.java:4011)
at com.sun.ejb.containers.EJBLocalObjectInvocationHandler.invoke(EJBLocalObjectInvocationHandler.java:197)
at com.sun.ejb.containers.EJBLocalObjectInvocationHandlerDelegate.invoke(EJBLocalObjectInvocationHandlerDelegate.java:127)
at $Proxy120.findById(Unknown Source)
at com.mirodinero.web.servlets.setMisDatos.processRequest(setMisDatos.java:96)
at com.mirodinero.web.servlets.setMisDatos.doGet(setMisDatos.java:140)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:734)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:847)
at org.apache.catalina.core.ApplicationFilterChain.servletService(ApplicationFilterChain.java:427)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:315)
at org.apache.catalina.core.StandardContextValve.invokeInternal(StandardContextValve.java:287)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:218)
at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:648)
at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:593)
at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:94)
at com.sun.enterprise.web.PESessionLockingStandardPipeline.invoke(PESessionLockingStandardPipeline.java:98)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:222)
at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:648)
at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:593)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:587)
at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:1096)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:166)
at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:648)
at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:593)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:587)
at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:1096)
at org.apache.coyote.tomcat5.CoyoteAdapter.service(CoyoteAdapter.java:288)
at com.sun.enterprise.web.connector.grizzly.DefaultProcessorTask.invokeAdapter(DefaultProcessorTask.java:647)
at com.sun.enterprise.web.connector.grizzly.DefaultProcessorTask.doProcess(DefaultProcessorTask.java:579)
at com.sun.enterprise.web.connector.grizzly.DefaultProcessorTask.process(DefaultProcessorTask.java:831)
at com.sun.enterprise.web.connector.grizzly.DefaultReadTask.executeProcessorTask(DefaultReadTask.java:341)
at com.sun.enterprise.web.connector.grizzly.DefaultReadTask.doTask(DefaultReadTask.java:263)
at com.sun.enterprise.web.connector.grizzly.DefaultReadTask.doTask(DefaultReadTask.java:214)
at com.sun.enterprise.web.connector.grizzly.TaskBase.run(TaskBase.java:265)
at com.sun.enterprise.web.connector.grizzly.ssl.SSLWorkerThread.run(SSLWorkerThread.java:106)
所以我去检查出现错误的文件,代码如下所示:

public DatosUsuario findById(String id) {
    DatosUsuario du = null;
    try {
        du = (DatosUsuario) em.createNamedQuery("DatosUsuario.findByIdUsuario").setParameter("idUsuario", id).getSingleResult();
    } catch (Exception nre) {
        log.error("No existe el usuario: " + id + ", ex: ", nre);
    } finally {
        log.debug("du: " + du);
        return du;
    }
}
有人知道错误在哪里吗?因为在我的网页中,它看起来像是保存了三次数据中的两次

是的,实际上EntityExistExpection在这里给出:

public void create(DatosUsuario datosUsuario) {
    em.persist(datosUsuario);  // in this line
}

public void edit(DatosUsuario datosUsuario) {
    em.merge(datosUsuario);
}

public void remove(DatosUsuario datosUsuario) {
    em.remove(em.merge(datosUsuario));
}

但我想这是创建新用户所必需的,对吗?还是应该检查用户是否存在,然后编辑数据?如何做到这一点?

第一个异常是由分离的对象引起的,这可能有几个原因。就像它是已经结束的事务的一部分,或者它是已经关闭的上下文的一部分。当您想在新的事务/上下文中使用它时,您需要在实体管理器上调用merge


您发布的最后一个异常是由于将id传递给findById函数而导致的,该函数的数据库中不存在对象。getSingleResult()的行为是,如果没有一个结果,则引发异常。

可能会引发EntityExistsException,因为您需要执行em.merge()而不是em.persist()

您应该创建一个save()方法,当实体不是新的且需要保存时,客户端将调用该方法

public void save(DatosUsuario datosUsuario) {
    em.merge(datosUsuario);
}
或者,您可以保留create()方法并检查实体是否已持久化。具有@Id和@GeneratedValue(strategy=GenerationType.AUTO)的实体只有在持久化时才具有Id。所以像这样的东西可以起作用:

public void createOrSave(DatosUsuario datosUsuario) {
    if (datosUsuario.getId() == null){
        em.persist(datosUsuario);
    }
    else{
        em.merge(datosUsuario);
    }
}

您向我们展示了试图检索分离对象的代码,该对象从未被持久化,因此您得到了一个
NoResultException
。我们需要查看
com.mirodinero.sesionBean.datosuariofeacade.create
,以了解为什么首先要分离实体。这根本不是答案。这是一个评论。谁会投票给一个只说“给我更多信息”的答案?好的,我会更多地使用评论功能。答案改进了。实际上我已经有了save()函数,但没有复制它。我甚至成功地编写了一个与您非常相似的代码,但在if条件中没有.getID。。。仍然不知道它是否工作完美,必须在新用户身上测试它,以检查它是否解决了我的问题。