I'm getting the error:
org.hibernate.HibernateException: A collection with cascade="all-delete-orphan" was no longer referenced by the owning entity instance: house.datamodel.User.roles
Now I've read the doco, and it says not to replace any collections. But I'm not. I even declared my collections to be final, just to make sure they're not.
The scenario is Users and Roles, that everyone is probably familiar with in a JEE web server:
The error happens in various scenarios, including queries, but it even happens if I don't actually modify any objects, and then it happens on commit.
Code:
drop table roles;
drop table users;
create table users (
user_id varchar(100) constraint user_pk primary key,
name varchar(100) not null,
password varchar(100),
email varchar(100)
);
create table roles (
user_id varchar(100) not null constraint role_user_fk references users(user_id) on delete cascade,
role_id varchar(100) not null,
constraint user_role_pk primary key(user_id, role_id)
);
Code:
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="house.datamodel.User" table="users">
<meta attribute="class-description">
Roles
</meta>
<id name="userId" column="user_id" type="string" />
<property name="name" column="name" type="string" />
<property name="password" column="password" type="string" />
<property name="email" column="email" type="string" />
<set name="roles" inverse="true" lazy="false" cascade="all,delete-orphan">
<key column="user_id" on-delete="cascade" not-null="true"/>
<one-to-many class="house.datamodel.Role" />
</set>
</class>
</hibernate-mapping>
Code:
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="house.datamodel.Role" table="roles">
<meta attribute="class-description">
Roles
</meta>
<composite-id>
<key-property name="roleId" column="role_id" type="string" />
<key-property name="userId" column="user_id" type="string" />
</composite-id>
<natural-id>
<many-to-one name="user" column="user_id" insert="false"
update="false" not-null="true" class="house.datamodel.User" />
</natural-id>
</class>
</hibernate-mapping>
Code:
package house.datamodel;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
public class User {
private String email;
private String userId;
private String name;
private String password;
private final Set<Role> roles = new HashSet<>();
public User() {
}
public String getUserId() {
return userId;
}
public void setUserId(String userId) {
this.userId = userId;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public Set<Role> getRoles() {
return roles;
}
public void setRoles(Set<Role> roles) {
this.roles.clear();
this.roles.addAll(roles);
}
public String[] getRoleStrings() {
String[] rtn = new String[getRoles().size()];
int i = 0;
for (Role r : getRoles()) {
rtn[i++] = r.getRoleId();
}
return rtn;
}
public void setRoleStrings(String[] roleStrings) {
Set<Role> newRoles = new HashSet<>(roleStrings.length);
Map<String,Role> oldRoles = new HashMap<>(getRoles().size());
for (Role r : getRoles()) {
oldRoles.put(r.getRoleId(), r);
}
// Important to reuse old objects or hibernate chokes.
for (String rs : roleStrings) {
if (oldRoles.containsKey(rs)) {
newRoles.add(oldRoles.get(rs));
} else {
Role r = new Role();
r.setUser(this);
r.setUserId(userId);
r.setRoleId(rs);
newRoles.add(r);
}
}
setRoles(newRoles);
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String toString() {
return "[Users: userId=" + getUserId() + " name=" + getName() + " roles: " + getRoles() + "]";
}
}
Code:
package house.datamodel;
import java.io.Serializable;
public class Role implements Serializable {
private static final long serialVersionUID = 1L;
String userId;
String roleId;
User user;
public String getUserId() {
return userId;
}
public void setUserId(String userId) {
this.userId = userId;
}
public String getRoleId() {
return roleId;
}
public void setRoleId(String roleId) {
this.roleId = roleId;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
public String toString() {
return "[Role: userId=" + getUserId() + " roleId=" + getRoleId() + "]";
}
public boolean equals(Object o) {
if (!(o instanceof Role)) {
return false;
}
return getUserId().equals(((Role)o).getUserId())
&& getRoleId().equals(((Role)o).getRoleId());
}
public int hashCode() {
return userId.hashCode() + roleId.hashCode();
}
}
Code:
21:30:39,959 ERROR [stderr] (default task-4) org.hibernate.HibernateException: A collection with cascade="all-delete-orphan" was no longer referenced by the owning entity instance: house.datamodel.User.roles
21:30:39,959 ERROR [stderr] (default task-4) at org.hibernate.engine.internal.Collections.processDereferencedCollection(Collections.java:114)
21:30:39,959 ERROR [stderr] (default task-4) at org.hibernate.engine.internal.Collections.processUnreachableCollection(Collections.java:67)
21:30:39,960 ERROR [stderr] (default task-4) at org.hibernate.event.internal.AbstractFlushingEventListener.flushCollections(AbstractFlushingEventListener.java:258)
21:30:39,960 ERROR [stderr] (default task-4) at org.hibernate.event.internal.AbstractFlushingEventListener.flushEverythingToExecutions(AbstractFlushingEventListener.java:103)
21:30:39,960 ERROR [stderr] (default task-4) at org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:55)
21:30:39,960 ERROR [stderr] (default task-4) at org.hibernate.internal.SessionImpl.flush(SessionImpl.java:1222)
21:30:39,960 ERROR [stderr] (default task-4) at org.hibernate.internal.SessionImpl.managedFlush(SessionImpl.java:425)
21:30:39,960 ERROR [stderr] (default task-4) at org.hibernate.engine.transaction.internal.jdbc.JdbcTransaction.beforeTransactionCommit(JdbcTransaction.java:101)
21:30:39,960 ERROR [stderr] (default task-4) at org.hibernate.engine.transaction.spi.AbstractTransactionImpl.commit(AbstractTransactionImpl.java:177)
21:30:39,960 ERROR [stderr] (default task-4) at house.screenlogic.EditFlatmate.save(EditFlatmate.java:109)
21:30:39,960 ERROR [stderr] (default task-4) at house.screenlogic.EditFlatmate$Proxy$_$$_WeldClientProxy.save(Unknown Source)
21:30:39,960 ERROR [stderr] (default task-4) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
21:30:39,961 ERROR [stderr] (default task-4) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
21:30:39,961 ERROR [stderr] (default task-4) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
21:30:39,961 ERROR [stderr] (default task-4) at java.lang.reflect.Method.invoke(Method.java:483)
21:30:39,961 ERROR [stderr] (default task-4) at com.sun.el.parser.AstValue.invoke(AstValue.java:275)
21:30:39,961 ERROR [stderr] (default task-4) at com.sun.el.MethodExpressionImpl.invoke(MethodExpressionImpl.java:304)
21:30:39,961 ERROR [stderr] (default task-4) at org.jboss.weld.util.el.ForwardingMethodExpression.invoke(ForwardingMethodExpression.java:40)
21:30:39,961 ERROR [stderr] (default task-4) at org.jboss.weld.el.WeldMethodExpression.invoke(WeldMethodExpression.java:50)
21:30:39,961 ERROR [stderr] (default task-4) at org.jboss.weld.util.el.ForwardingMethodExpression.invoke(ForwardingMethodExpression.java:40)
21:30:39,961 ERROR [stderr] (default task-4) at org.jboss.weld.el.WeldMethodExpression.invoke(WeldMethodExpression.java:50)
21:30:39,961 ERROR [stderr] (default task-4) at com.sun.faces.facelets.el.TagMethodExpression.invoke(TagMethodExpression.java:105)
21:30:39,961 ERROR [stderr] (default task-4) at javax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:87)
21:30:39,962 ERROR [stderr] (default task-4) at com.sun.faces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:102)
21:30:39,962 ERROR [stderr] (default task-4) at javax.faces.component.UICommand.broadcast(UICommand.java:315)
21:30:39,962 ERROR [stderr] (default task-4) at javax.faces.component.UIViewRoot.broadcastEvents(UIViewRoot.java:790)
21:30:39,962 ERROR [stderr] (default task-4) at javax.faces.component.UIViewRoot.processApplication(UIViewRoot.java:1282)
21:30:39,962 ERROR [stderr] (default task-4) at com.sun.faces.lifecycle.InvokeApplicationPhase.execute(InvokeApplicationPhase.java:81)
21:30:39,962 ERROR [stderr] (default task-4) at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
21:30:39,962 ERROR [stderr] (default task-4) at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:198)
21:30:39,962 ERROR [stderr] (default task-4) at javax.faces.webapp.FacesServlet.service(FacesServlet.java:646)
21:30:39,962 ERROR [stderr] (default task-4) at io.undertow.servlet.handlers.ServletHandler.handleRequest(ServletHandler.java:85)
21:30:39,962 ERROR [stderr] (default task-4) at io.undertow.servlet.handlers.security.ServletSecurityRoleHandler.handleRequest(ServletSecurityRoleHandler.java:61)
21:30:39,963 ERROR [stderr] (default task-4) at io.undertow.servlet.handlers.ServletDispatchingHandler.handleRequest(ServletDispatchingHandler.java:36)
21:30:39,963 ERROR [stderr] (default task-4) at org.wildfly.extension.undertow.security.SecurityContextAssociationHandler.handleRequest(SecurityContextAssociationHandler.java:78)
21:30:39,963 ERROR [stderr] (default task-4) at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:25)
21:30:39,963 ERROR [stderr] (default task-4) at io.undertow.servlet.handlers.security.SSLInformationAssociationHandler.handleRequest(SSLInformationAssociationHandler.java:113)
21:30:39,963 ERROR [stderr] (default task-4) at io.undertow.security.handlers.AuthenticationCallHandler.handleRequest(AuthenticationCallHandler.java:52)
21:30:39,963 ERROR [stderr] (default task-4) at io.undertow.security.handlers.AuthenticationConstraintHandler.handleRequest(AuthenticationConstraintHandler.java:51)
21:30:39,963 ERROR [stderr] (default task-4) at io.undertow.security.handlers.AbstractConfidentialityHandler.handleRequest(AbstractConfidentialityHandler.java:45)
21:30:39,963 ERROR [stderr] (default task-4) at io.undertow.servlet.handlers.security.ServletConfidentialityConstraintHandler.handleRequest(ServletConfidentialityConstraintHandler.java:61)
21:30:39,963 ERROR [stderr] (default task-4) at io.undertow.servlet.handlers.security.ServletSecurityConstraintHandler.handleRequest(ServletSecurityConstraintHandler.java:56)
21:30:39,963 ERROR [stderr] (default task-4) at io.undertow.security.handlers.AuthenticationMechanismsHandler.handleRequest(AuthenticationMechanismsHandler.java:58)
21:30:39,963 ERROR [stderr] (default task-4) at io.undertow.servlet.handlers.security.CachedAuthenticatedSessionHandler.handleRequest(CachedAuthenticatedSessionHandler.java:70)
21:30:39,964 ERROR [stderr] (default task-4) at io.undertow.security.handlers.SecurityInitialHandler.handleRequest(SecurityInitialHandler.java:76)
21:30:39,964 ERROR [stderr] (default task-4) at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:25)
21:30:39,964 ERROR [stderr] (default task-4) at org.wildfly.extension.undertow.security.jacc.JACCContextIdHandler.handleRequest(JACCContextIdHandler.java:61)
21:30:39,964 ERROR [stderr] (default task-4) at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:25)
21:30:39,964 ERROR [stderr] (default task-4) at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:25)
21:30:39,964 ERROR [stderr] (default task-4) at io.undertow.servlet.handlers.ServletInitialHandler.handleFirstRequest(ServletInitialHandler.java:240)
21:30:39,964 ERROR [stderr] (default task-4) at io.undertow.servlet.handlers.ServletInitialHandler.dispatchRequest(ServletInitialHandler.java:227)
21:30:39,964 ERROR [stderr] (default task-4) at io.undertow.servlet.handlers.ServletInitialHandler.access$000(ServletInitialHandler.java:73)
21:30:39,964 ERROR [stderr] (default task-4) at io.undertow.servlet.handlers.ServletInitialHandler$1.handleRequest(ServletInitialHandler.java:146)
21:30:39,964 ERROR [stderr] (default task-4) at io.undertow.server.Connectors.executeRootHandler(Connectors.java:168)
21:30:39,964 ERROR [stderr] (default task-4) at io.undertow.server.HttpServerExchange$1.run(HttpServerExchange.java:687)
21:30:39,965 ERROR [stderr] (default task-4) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
21:30:39,965 ERROR [stderr] (default task-4) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
21:30:39,965 ERROR [stderr] (default task-4) at java.lang.Thread.run(Thread.java:744)