Reputation: 683
I have an Entity that has two relation manyToMany with itself and I don't want to use Cascade.MERGE because I need to do some data checks to validate the data:
@Entity("device")
public class Device {
...
@ManyToMany(mappedBy = "parents", targetEntity = Device.class, fetch = FetchType.LAZY)
public Set<Device> getChildren() {
return this.children;
}
@Override
@ManyToMany(targetEntity = Device.class, fetch = FetchType.LAZY)
@JoinTable(name = "dem_hierarchy", joinColumns = {
@JoinColumn(name = "CHILDREN_UUID", referencedColumnName = "UUID")},
inverseJoinColumns = {
@JoinColumn(name = "DEM_DEVICE_UUID", referencedColumnName = "UUID")})
public Set<Device> getParents() {
return parents;
}
...
}
When I save a tree like this:
Device grandGrandPa = new Device();
grandGrandPa.setName("TEST" + counter + "_grandGrandPa");
Device grandPa = new Device();
grandPa.setName("TEST" + counter + "_grandPa");
grandGrandPa.addChild(grandPa);
Device daddy = new Device();
daddy.setName("TEST" + counter + "_daddy");
grandPa.addChild(daddy);
Device son = new Device();
son.setName("TEST" + counter + "_son");
daddy.addChild(son);
grandGrandPa = deviceService.register(grandGrandPa);
The register method is recursive and it descends the tree using the children column. When its the turn of the "grandPa" to be saved the weblogic return an exception:
Caused by: org.hibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing
I cannot understand why this happens. It gives me this error when in code there are some queries on parent Device: first turn it is empty, second turn it has one value. I'm using weblogic 12.1.3 and hibernate 4.0.0, as database Oracle 11g.
Upvotes: 0
Views: 1356
Reputation: 10726
It gives me this error when in code there are some queries on parent Device
By default, Hibernate will flush pending changes to the database before attempting to execute a query. At that stage, all entities referenced in all relationships should have been persisted, or else an exception will be thrown.
Also, since mappedBy
is declared on the children
end, the parents
is the owning side of the relationship. Because of that, Hibernate will ignore children
completely at persist time and look for transient entities in parents
instead. Your persisting logic should therefore be reversed - save parents first, children last (alternatively, you could simply declare children
the owning side).
Upvotes: 1