2012-05-05 91 views
0

我跟一個連接到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.DatosUsuario [idUsuario = Miguel LLorente]]。 Class> com.mirodinero.entidad.DatosUsuario主鍵> [Miguel LLorente] at oracle.toplink.essentials.internal.ejb.cmp3.base.EntityManagerImpl.persist(EntityManagerImpl.java:224) at com.sun.enterprise .util.EntityManagerWrapper.persist(EntityManagerWrapper.java:440) 在com.mirodinero.sesionBean.DatosUsuarioFacade.create(DatosUsuarioFacade.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.runMeth處的OD(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) at com.sun.ejb.containers.EJBLocalObjectInvocationHandler.invoke(EJBLocalObjectInvocationHandler.java:197) ... 33更多 引起異常[ TOPLINK-7231](Oracle TopLink Essentials - 2.1(Build b60e-fcs(12/23/2008))):oracle.toplink.essentials.exceptions.ValidationException 異常說明:無法保留分離的對象[com.mirodinero.entidad.DatosUsuario [idUsuario = Miguel LLorente]]。 類> com.mirodinero.entidad.DatosUsuario主鍵> [Miguel LLorente] at oracle.toplink.essentials.exceptions.ValidationException.cannotPersistExistingObject(ValidationException.java:2171) at 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) at 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; 
    } 
} 

有誰知道哪裏出錯?因爲在我的網頁中,它看起來像是將數據2保存了3次。

是,其實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)); 
} 

,但我想它是需要創建新的用戶,對不對?還是應該檢查用戶是否存在,然後編輯數據?如何做呢?

+0

你向我們展示了代碼,你試圖檢索分離的對象,它永遠不會被持久化,所以你會得到一個'NoResultException'。我們需要看到'com.mirodinero.sesionBean.DatosUsuarioFacade.create'來找出爲什麼實體首先被分離。 –

回答

1

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); 
    } 
} 
+0

這完全不是答案。這是一條評論。誰提出了一個剛剛說「給我更多信息」的答案? –

+0

好點,我會更多地使用評論功能。答案改進了。 –

+0

實際上我已經有了save()函數,但沒有複製它。我甚至設法編寫了一個與你的代碼非常相似的代碼,但在if條件中沒有.getID ...仍然不知道它是否完美工作,必須在新用戶上測試它是否能解決我的問題。 – Stefano

0

第一個異常是由一個對象被分離引起的,可能有幾個原因。就像它是已經結束的事務的一部分,或者它是被關閉的上下文的一部分。當你想在新的事務/上下文中使用它時,你需要在實體管理器上調用合併。

您發佈的最後一個異常是由於將ID傳遞給您的findById函數而導致的,該函數在數據庫中不存在任何對象。 getSingleResult()的行爲是在沒有一個結果的情況下拋出異常。