I have a class that references parent instances and child instances of the same type:
Code:
@Entity
public class BusinessInstance {
@Id
private String id = UUID.getUUID().toString();
@ManyToMany(fetch=FetchType.LAZY)
@JoinTable(name="BusinessHierarchy", joinColumns=@JoinColumn(name="childId"),
inverseJoinColumns=@JoinColumn(name="parentId"))
@Fetch(value=FetchMode.SELECT)
@LazyCollection(value=LazyCollectionOption.TRUE)
private Set<BusinessInstance> parentInstances = new HashSet<BusinessInstance>();
@ManyToMany(mappedBy="parentInstances",fetch=FetchType.LAZY)
@Fetch(value=FetchMode.SELECT)
@LazyCollection(value=LazyCollectionOption.TRUE)
private Set<BusinessInstance> childInstances = new HashSet<BusinessInstance>();
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public Set<BusinessInstance> getParentInstances() {
return parentInstances;
}
public void setParentInstances(Set<BusinessInstance> parentInstances) {
this.parentInstances = parentInstances;
}
public Set<BusinessInstance> getChildInstances() {
return childInstances;
}
public void setChildInstances(Set<BusinessInstance> childInstances) {
this.childInstances = childInstances;
}
//adders / removers
public void addChild(BusinessInstance child) {
this.getChildInstances().add(child);
child.getParentInstances().add(this);
}
public void removeChild(BusinessInstance child) {
child.getParentInstances().remove(instanceInSet);
this.getChildInstances().remove(instanceInSet);
}
}
Removing children from an instance usually works well. However, in some situations the removal does not work. Hours of debugging showed that in these situations the application tries to remove an object of type BusinessInstance, but the childInstance collection only contains objects of a proxy class (like "BusinessInstance_$$javaassist23"). In these situations, hibernate does not find that object in that collection so that it does not get removed. For debugging purposes, I've written this helper method to get the proxy class object of a BusinessInstance object from a collection:
Code:
private BusinessInstance getInstanceInSet(BusinessInstance referenceInstance, Set<BusinessInstance> instances) {
if(instances.contains(referenceInstance)) {
return referenceInstance;
}
BusinessInstance originalInstance;
BusinessInstance hibProxyInstance;
for(BusinessInstance instance : instances) {
if(instance instanceof HibernateProxy) {
if(referenceInstance.equals((BusinessInstance) ((HibernateProxy)instance).getHibernateLazyInitializer().getImplementation())) {
return instance;
}
}
}
return null;
}
If I use this method in the removeChild() method, the removal works. However, this is not the way Hibernate should behave, right? I've tested it with Hibernate 3.2 and 3.5.3 and both versions show the same behavior. Sadly, I was not able to create a simple test case that shows the same error. The removeChild() works well 99% of the time, but for some objects, it doesn't. The initialisation of the objects always works the same way. Does anyone has a suggestion?
Thanks in advance.