Hi,
More info, of course, excuse me.
Please, note that this is a unit test... I think there could be a case in which, in the same session, children would be deleted and then the parent (of course, more things would happen between those two delete() calls)
My code is something like, in lines 38-39 of TestAgenteAislarFallo.java:
Code:
mgr2.delete(ag2);
mgr2.delete(ag2.getNIFPassword());
Being that NIFPassword cascade-deletes manually (in its onDelete) the related object, ag2... this is a case of "first I will delete the children. then I will delete the parent", and the parent will anyway try to delete it's associated children (though they've been already deleted).
mgr2.delete() is just a wrapper to Session.delete()
The NIFPassword object onDelete will not even try to delete anything really, because it shares the session, and it's only child has already been deleted (in the previous line).
this is the stack trace I get:
Code:
1) testCGMB(com.previsora.tests.data.TestAgenteAislarFallo)java.lang.IllegalArgumentException: fromIndex(1) > toIndex(0)
at java.util.SubList.<init>(AbstractList.java:706)
at java.util.RandomAccessSubList.<init>(AbstractList.java:860)
at java.util.AbstractList.subList(AbstractList.java:569)
at net.sf.hibernate.impl.SessionImpl.doDelete(SessionImpl.java:1155)
at net.sf.hibernate.impl.SessionImpl.delete(SessionImpl.java:1114)
at com.previsora.data.hibernate.HibernateManager.delete(HibernateManager.java:377)
at com.previsora.tests.data.TestAgenteAislarFallo.testCGMB(TestAgenteAislarFallo.java:39)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at com.intellij.rt.execution.junit.TextTestRunner.main(TextTestRunner.java:12)
I'm tracking Hibernate's source in order to try to understand what I'm doing wrong. In line 1155 of SessionImpl:
Code:
deletionsByOnSave = deletions.subList( oldDeletions.size(), deletions.size() );
The size of deletion is 0, and oldDeletion's is 1, so subList it will throw the IllegalArgumentException.
This is in the context of:
Code:
if ( persister.implementsLifecycle() ) {
HashSet oldNullifiables = (HashSet) nullifiables.clone();
ArrayList oldDeletions = (ArrayList) deletions.clone();
log.debug("calling onDelete()");
if ( ( (Lifecycle) object ).onDelete(this) ) {
//rollback deletion
entry.status = LOADED;
entry.deletedState = null;
log.debug("deletion vetoed by onDelete()");
return; //don't let it cascade
}
deletionsByOnSave = deletions.subList( oldDeletions.size(), deletions.size() );
deletions = oldDeletions;
nullifiablesByOnSave = nullifiables;
nullifiables = oldNullifiables;
}
Trying to understand the code (excuse me if I throw bizarre assumptions here :-() while debugging:
* deletions holds scheduled deletions in the session, in my case there is one before calling onDelete.
* oldDeletions is a clone of the previous state of deletions (and so also has a size of 1)
* after the call to onDelete, deletions will contain NO elements?? Why? I haven't deleted anything, and I haven't made neither flush() nor close()... can't understand this.
So I track again the onDelete, and get that I run a session.find() in there, in order to get the amount of related objects I will delete... and seems like this session.find() would reset the "deletions" list...
Then, I will track session.find() and get that if AutoFlush == true, and dontFlushFromFind is 0, it will flush my collections, and so my 'deletions' will be 0, leading to my Exception...
I've checked what that dontFlushFromFind is, and seems like it's a control to avoid flushing too early when a find is recursively called... should that be of application to my code? Is this control needed in the delete too??
I still don't get why should this code have worked without problem in the previous version...
* Am I allowed to run a find inside an onDelete? If so... should I try to avoid this in some way?? (maybe changing the AutoFlush property?)
* Is this the correct behaviour, or was it correct in the previous Hibernate version?
Thank you very much!
_
Jorge