Hello everyone,
I have a question, is there a way to solve the following problem and leaving cascade="all-delete-orphan".
Here is a mapping snippet that maps a map:
Code:
<map name="properties"
cascade="all-delete-orphan"
table="Properties"
lazy="false"
inverse="true"
order-by="NAME asc">
<key column="CI_ID"/>
<index column="NAME" type="string"/>
<one-to-many class="Property"/>
</map>
now here is the exact part of an equals method that causes the problem:
Code:
/**
* if two CIs has the same database Identity they are deemed
* equals. If they have not been persisted yet, equality is
* decided by checking important state fields:
*
* 1. type
* 2. properties count.
* 3. all properties. (@see com.etagon.csmc.model.Property.equals())
*
* children aren't taken into account.
*/
public boolean equals(Object o){
....... beginning omitted .........
if (other.getReadOnlyProperties() != null &&
this.properties != null) {
if (other.getPropertiesCount()
!= this.properties.size())
return false;
Map<String, Property> m = other.getReadOnlyProperties();
Collection<Property> c = properties.values();
for (Property p : c) {
if (!m.containsKey(p.getName())) return false;
else if (!m.containsValue(p)) return false;
}
}
return true;
}
if I do this:
Code:
public boolean equals(Object o){
....... beginning omitted .........
if (other.properties != null &&
this.properties != null) {
if (other.properties.size() != this.properties.size())
return false;
// for (Property p : properties.values()) {
// if (!other.properties.containsKey(p.getName()))
// return false;
// else if (!other.properties.containsValue(p))
// return false;
// }
}
return true;
}
I know why I get the "Don't dereference a collection.....all-delete-orphan..."
Without creating references to the properties map of the "other" it is quite difficult to perform equality check. So if anyone have any ideas I'd be happy to hear them. I do hope that change to cascade="all" isn't the only way.
I also understand why you shouldn't dereference a collection to a point where it GCed, but i fail to understand why this (or similar) situations can cause any problem, unless it is impossible to distinguish between the two.
BTW: in case my title or content upset someone, I think hibernate is a great piece of software and thought!
so no hard feeling, I'm just asking :)
TIA
Yaniv
Hibernate 3b
org.hibernate.HibernateException: Don't dereference a collection with cascade="all-delete-orphan": com.etagon.csmc.model.CI.properties
at org.hibernate.engine.Collections.updateUnreachableCollection(Collections.java:59)
at org.hibernate.event.AbstractFlushingEventListener.flushCollections(AbstractFlushingEventListener.java:192)
at org.hibernate.event.AbstractFlushingEventListener.flushEverythingToExecutions(AbstractFlushingEventListener.java:65)
at org.hibernate.event.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:25)
at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:814)
at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:75)
at com.etagon.csmc.model.TestCI_AndTemplatePersistence.tearDown(TestCI_AndTemplatePersistence.java:65)
at junit.framework.TestCase.runBare(TestCase.java:130)
at junit.framework.TestResult$1.protect(TestResult.java:106)
at junit.framework.TestResult.runProtected(TestResult.java:124)
at junit.framework.TestResult.run(TestResult.java:109)
at junit.framework.TestCase.run(TestCase.java:118)
at junit.framework.TestSuite.runTest(TestSuite.java:208)
at junit.framework.TestSuite.run(TestSuite.java:203)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:421)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:305)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:186)
MySQL