Hibernate version: 3.2 GA
Mapping documents: Annotations
Name and version of the database you are using:MySQL 5
Hello, I ran into some issues while deleting detached objects. Although i've already found a workaround i would like to be able to understand exactly what i was doing wrong.
Basically i have a list page for my entities and a "delete" button is rendered to each of the rows. This button is bound to an action.
This is my entity is the standard entity generated with NetBeans, the only change i've made is using an UUID in a String for an Id.
Code:
import java.io.Serializable;
import java.util.UUID;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.Table;
@Entity
public class UserEntity implements Serializable {
/*buncha fields*/
@Id
@Column(name = "id", nullable = false)
private String id;
public UserEntity() {
UUID uuid = UUID.randomUUID();
this.setId(uuid.toString());
}
/*buncha setters and getters*/
public java.lang.String getId() {
return this.id;
}
public void setId(java.lang.String id) {
this.id = id;
}
@Override
public int hashCode() {
int hash = 0;
hash += (this.id != null ? this.id.hashCode() : 0);
return hash;
}
@Override
public boolean equals(Object object) {
if (!(object instanceof UserEntity)) {
return false;
}
UserEntity other = (UserEntity)object;
if (this.id != other.id && (this.id == null || !this.id.equals(other.id))) return false;
return true;
}
}
Action in backing bean.
Code:
public String userDeleteButton_action() {
this.getUserEntityFacade().destroyById(this.getUserEntityId());
return null;
}
And my Facade looks like this:
Code:
public void destroyById(Object pk) {
try {
UserEntity userToDelete;
Session session;
HibernateEntityManager hEntityManager;
Query deleteQuery;
int modifiedRecords;
hEntityManager = (HibernateEntityManager)entityManager.getDelegate();
session = hEntityManager.getSession();
userTransaction.begin();
deleteQuery = session.createQuery("delete UserEntity where id = ?");
deleteQuery.setParameter(0,pk.toString());
modifiedRecords = deleteQuery.executeUpdate();
userTransaction.commit();
} catch (Exception e){
this.getLog().log(Level.SEVERE,"error when deleting entity by id",e);
}
}
The above code works perfectly. However, i would prefer to be able to use the
session.delete(userEntity) method. (and also understand the attached/detached problem when deleting) I was not able to use it due to an "object detached" exception. This is what i was trying to do:
Code:
public void destroyById(Object pk) {
try {
...
userTransaction.begin();
userToDelete = (UserEntity) session.get(UserEntity.class,(String)pk);
session.delete("UserEntity",userToDelete);
userTransaction.commit();
} catch ...
}
I was also trying to use
Code:
userToDelete = session.merge(userToDelete)
but to no avail ... :-(
stack trace:
Code:
java.lang.IllegalArgumentException: Removing a detached instance UserEntity#403ee448-e79f-439f-9385-ae129325bbb0
at org.hibernate.ejb.event.EJB3DeleteEventListener.performDetachedEntityDeletionCheck(EJB3DeleteEventListener.java:47)
at org.hibernate.event.def.DefaultDeleteEventListener.onDelete(DefaultDeleteEventListener.java:75)
at org.hibernate.event.def.DefaultDeleteEventListener.onDelete(DefaultDeleteEventListener.java:49)
at org.hibernate.impl.SessionImpl.fireDelete(SessionImpl.java:766)
at org.hibernate.impl.SessionImpl.delete(SessionImpl.java:751)
at com.pset.pbnk.ejb.Facade.UserEntityFacade.destroyById(UserEntityFacade.java:121)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:585)
at com.sun.enterprise.security.application.EJBSecurityManager.runMethod(EJBSecurityManager.java:1050)
at com.sun.enterprise.security.SecurityUtil.invoke(SecurityUtil.java:165)
at com.sun.ejb.containers.BaseContainer.invokeTargetBeanMethod(BaseContainer.java:2766)
at com.sun.ejb.containers.BaseContainer.intercept(BaseContainer.java:3847)
at com.sun.ejb.containers.EJBObjectInvocationHandler.invoke(EJBObjectInvocationHandler.java:190)
at com.sun.ejb.containers.EJBObjectInvocationHandlerDelegate.invoke(EJBObjectInvocationHandlerDelegate.java:110)
at $Proxy75.destroyById(Unknown Source)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:585)
at com.sun.corba.ee.impl.presentation.rmi.StubInvocationHandlerImpl.privateInvoke(StubInvocationHandlerImpl.java:200)
at com.sun.corba.ee.impl.presentation.rmi.StubInvocationHandlerImpl.invoke(StubInvocationHandlerImpl.java:119)
at com.sun.corba.ee.impl.presentation.rmi.bcel.BCELStubBase.invoke(BCELStubBase.java:197)
at com.pset.pbnk.ejb.Facade.__UserEntityFacadeRemote_Remote_DynamicStub.destroyById(__UserEntityFacadeRemote_Remote_DynamicStub.java)
at com.pset.pbnk.ejb.Facade._UserEntityFacadeRemote_Wrapper.destroyById(com.pset.pbnk.ejb.Facade._UserEntityFacadeRemote_Wrapper.java)
at com.pset.pbnk.web.users.UserEntityListPage.userDeleteButton_action(UserEntityListPage.java:453)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:585)
at com.sun.el.parser.AstValue.invoke(AstValue.java:151)
at com.sun.el.MethodExpressionImpl.invoke(MethodExpressionImpl.java:283)
at javax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:77)
at com.sun.faces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:96)
at com.sun.rave.web.ui.appbase.faces.ActionListenerImpl.processAction(ActionListenerImpl.java:57)
at javax.faces.component.UICommand.broadcast(UICommand.java:383)
at com.sun.webui.jsf.component.WebuiCommand.broadcast(Unknown Source)
at com.sun.webui.jsf.component.TableRowGroup.broadcast(Unknown Source)
at javax.faces.component.UIViewRootCopy.broadcastEvents(UIViewRootCopy.java:452)
at com.sun.faces.extensions.avatar.components.PartialTraversalViewRoot.broadcastEvents(PartialTraversalViewRoot.java:362)
at javax.faces.component.UIViewRootCopy.processApplication(UIViewRootCopy.java:764)
at com.sun.faces.lifecycle.InvokeApplicationPhase.execute(InvokeApplicationPhase.java:97)
at com.sun.faces.lifecycle.LifecycleImpl.phase(LifecycleImpl.java:244)
at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:113)
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:244)
at org.apache.catalina.core.ApplicationFilterChain.servletService(ApplicationFilterChain.java:397)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:184)
at com.sun.webui.jsf.util.UploadFilter.doFilter(Unknown Source)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:216)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:184)
at org.netbeans.modules.web.monitor.server.MonitorFilter.doFilter(MonitorFilter.java:368)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:216)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:184)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:276)
at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:566)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:536)
at org.apache.catalina.core.StandardContextValve.invokeInternal(StandardContextValve.java:240)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:179)
at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:566)
at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:73)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:182)
at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:566)
at com.sun.enterprise.web.VirtualServerPipeline.invoke(VirtualServerPipeline.java:120)
at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:939)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:137)
at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:566)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:536)
at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:939)
at org.apache.coyote.tomcat5.CoyoteAdapter.service(CoyoteAdapter.java:239)
at com.sun.enterprise.web.connector.grizzly.ProcessorTask.invokeAdapter(ProcessorTask.java:667)
at com.sun.enterprise.web.connector.grizzly.ProcessorTask.processNonBlocked(ProcessorTask.java:574)
at com.sun.enterprise.web.connector.grizzly.ProcessorTask.process(ProcessorTask.java:844)
at com.sun.enterprise.web.connector.grizzly.ReadTask.executeProcessorTask(ReadTask.java:287)
at com.sun.enterprise.web.connector.grizzly.ReadTask.doTask(ReadTask.java:212)
at com.sun.enterprise.web.connector.grizzly.TaskBase.run(TaskBase.java:252)
at com.sun.enterprise.web.connector.grizzly.WorkerThread.run(WorkerThread.java:75)
I tried several ways to attach the instance again, using saveOrUpdate ... although it seems silly to select right before deletion.
Any pointers would be appreciated.