I used so far classic Hibernate with the "Session" Object and not using the JPA EntityManager. Now I introduced the JPA Listener/callback support by activating the service "org.hibernate.jpa.event.spi.JpaIntegrator" in my META-INF.
After that I get during the call "session.saveOrUpdate()" this error. The Listener I added was on another class and also if I remove there the "EntityListeners" JPA annotation, the error still appears.
java.lang.IllegalArgumentException: Removing a detached instance Attribute#233800
at org.hibernate.jpa.event.internal.core.JpaDeleteEventListener.performDetachedEntityDeletionCheck(JpaDeleteEventListener.java:69)
without this JPA Listener activation it was working fine.
My code is removing an object from the parent (detached - outside of a transaction), and then tries to save the parent with a new transaction. The child is owned by the parent and all changes should get cascaded? So what I need to do or is this a Bug of Hibernate?
I am using Hibernate v4.3.10
The Listener I added was on another class and also if I remove there the annotation, the error still appears.
Executed Code
Model model = modelDAO.getModelByCode("1234567");
model.removeAttribute("Description");
modelDAO.saveModel(model);
Implementation of the ModelDAO
protected Session getSession() {
return sessionFactory.getCurrentSession();
}
protected void beginTransaction() {
Session session = getSession();
Transaction transaction = session.getTransaction();
if (!transaction.isActive()) {
transaction.begin();
}
}
protected void handleTransaction() {
if (!bulkHandling) {
commitTransaction();
}
}
protected void commitTransaction() {
Session session = getSession();
Transaction transaction = session.getTransaction();
if (transaction.isActive()) {
transaction.commit();
}
}
protected void saveObject(Object obj) {
if(obj != null) {
try {
Session session = getSession();
beginTransaction();
if (!session.contains(obj)) {
session.saveOrUpdate(obj);
}
handleTransaction();
} catch (Exception ex) {
logger.error(ex.getMessage(),ex);
rollbackTransaction();
throw new HandledOneERPException(ex);
}
}
}
Model & Mapping
@Entity
public class Model extends AbstractERPEntity implements Translateable {
@OneToMany(cascade = CascadeType.ALL, fetch=FetchType.LAZY, orphanRemoval=true)
@JoinTable(name = "model_attributes", joinColumns = @JoinColumn(name = "model_id"), inverseJoinColumns = @JoinColumn(name = "attribute_id"))
@MapKey(name = "name")
private Map<String, Attribute<?>> attributes = new HashMap<String, Attribute<?>>();
Full Stack Trace
java.lang.IllegalArgumentException: Removing a detached instance ch.megloff.one.erp.model.attribute.Attribute#233800
at org.hibernate.jpa.event.internal.core.JpaDeleteEventListener.performDetachedEntityDeletionCheck(JpaDeleteEventListener.java:69) ~[hibernate-entitymanager-4.3.10.Final.jar:4.3.10.Final]
at org.hibernate.event.internal.DefaultDeleteEventListener.onDelete(DefaultDeleteEventListener.java:106) ~[hibernate-core-4.3.10.Final.jar:4.3.10.Final]
at org.hibernate.internal.SessionImpl.fireDelete(SessionImpl.java:965) ~[hibernate-core-4.3.10.Final.jar:4.3.10.Final]
at org.hibernate.internal.SessionImpl.delete(SessionImpl.java:909) ~[hibernate-core-4.3.10.Final.jar:4.3.10.Final]
at org.hibernate.engine.internal.Cascade.deleteOrphans(Cascade.java:437) ~[hibernate-core-4.3.10.Final.jar:4.3.10.Final]
at org.hibernate.engine.internal.Cascade.cascadeCollectionElements(Cascade.java:410) ~[hibernate-core-4.3.10.Final.jar:4.3.10.Final]
at org.hibernate.engine.internal.Cascade.cascadeCollection(Cascade.java:319) ~[hibernate-core-4.3.10.Final.jar:4.3.10.Final]
at org.hibernate.engine.internal.Cascade.cascadeAssociation(Cascade.java:296) ~[hibernate-core-4.3.10.Final.jar:4.3.10.Final]
at org.hibernate.engine.internal.Cascade.cascadeProperty(Cascade.java:161) ~[hibernate-core-4.3.10.Final.jar:4.3.10.Final]
at org.hibernate.engine.internal.Cascade.cascade(Cascade.java:118) ~[hibernate-core-4.3.10.Final.jar:4.3.10.Final]
at org.hibernate.engine.internal.Cascade.cascade(Cascade.java:86) ~[hibernate-core-4.3.10.Final.jar:4.3.10.Final]
at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.cascadeOnUpdate(DefaultSaveOrUpdateEventListener.java:375) ~[hibernate-core-4.3.10.Final.jar:4.3.10.Final]
at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.performUpdate(DefaultSaveOrUpdateEventListener.java:349) ~[hibernate-core-4.3.10.Final.jar:4.3.10.Final]
at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.entityIsDetached(DefaultSaveOrUpdateEventListener.java:244) ~[hibernate-core-4.3.10.Final.jar:4.3.10.Final]
at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.performSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:109) ~[hibernate-core-4.3.10.Final.jar:4.3.10.Final]
at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:90) ~[hibernate-core-4.3.10.Final.jar:4.3.10.Final]
at org.hibernate.internal.SessionImpl.fireSaveOrUpdate(SessionImpl.java:684) ~[hibernate-core-4.3.10.Final.jar:4.3.10.Final]
at org.hibernate.internal.SessionImpl.saveOrUpdate(SessionImpl.java:676) ~[hibernate-core-4.3.10.Final.jar:4.3.10.Final]
at org.hibernate.internal.SessionImpl.saveOrUpdate(SessionImpl.java:671) ~[hibernate-core-4.3.10.Final.jar:4.3.10.Final]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_65]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:1.8.0_65]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:1.8.0_65]
at java.lang.reflect.Method.invoke(Method.java:497) ~[?:1.8.0_65]
at org.hibernate.context.internal.ThreadLocalSessionContext$TransactionProtectionWrapper.invoke(ThreadLocalSessionContext.java:356) ~[hibernate-core-4.3.10.Final.jar:4.3.10.Final]
at com.sun.proxy.$Proxy70.saveOrUpdate(Unknown Source) ~[?:?]
at ch.megloff.common.dao.AbstractHibernateDAO.saveObject(AbstractHibernateDAO.java:261) [classes/:?]