Need help with Hibernate? Read this first:
http://www.hibernate.org/ForumMailingli ... AskForHelp
Hibernate version: 3.0.5
I can provide an application-independent test case as well as a patch for this issue, but I'm posting here first as a sanity check. If I am misusing the event hook functionality, I would be appreciative of any suggestsions on how otherwise I might go about what I am attempting to do here.
This is in the context of a web service using POJOs in a Java Servlet.
To handle the deletion or update of one or more Foo record, we have implemented in the application some fairly complex on update and on delete logic to synchronize 0 or more corresponding Bar records. This is primarily a matter of synchronizing date ranges: updating the date ranges of Bar records which overlap Foo records such that every day in the Bar record range interesects a Foo record, and deleting those Bar records which fall outside the date range of every Foo record.
Both Foo and Bar use Hibernate for persistence.
We have created our own DeleteEventListener and UpdateEventListener to implement this constraint logic.
So to the point: consider the condition C1, where a Foo entity is being deleted, where there is a Bar entity contained entirely by this Foo entity. In response to the deletion of the Foo entity, we want to delete the Bar entity.
So we have something like:
Code:
public boolean onPreDelete(PreDeleteEvent event) {
boolean value = super.onPreDelete(event);
if (!value) {
if (event.getEntity() instanceof Foo) {
if ([C1]) {
[session.delete B1 where B1 is the contained Bar record]
}
}
}
return value;
}
I can verify that the action to delete B1 is placed in the session's ActionQueue. Yet it is never executed.
I believe this is because of the following logic in ActionQueue:
Code:
private void executeActions(List list) throws HibernateException {
int size = list.size();
for ( int i = 0; i < size; i++ ) {
execute( (Executable) list.get(i) );
}
list.clear();
session.getBatcher().executeBatch();
}
I believe the loop should be checking the size of the queue every iteration. As it stands, the new deletion (the deletion of B1) added to the queue in response to the PreDeleteEvent will never be processed, because it is at an index in
list greater than
size - 1. The action is lost because
list.clear() (where list is
deletions) is executed after iterating over the elements initially in the list.
Also in ActionQueue:
Code:
public void executeActions() throws HibernateException {
executeActions( insertions );
executeActions( updates );
executeActions( collectionRemovals );
executeActions( collectionUpdates );
executeActions( collectionCreations );
executeActions( deletions );
}
Because it is also possible that we would add an update action (updating a corresponding Bar record) in response to a PreDeleteEvent for a Foo object, this block or method would need to be executed possibly repeatedly until it is true that all queues are empty. This could be either a while loop in this method having this as its condition, or a loop containing the invocation of this method having this as its condition.
Upon making these changes Hibernate performs as I expected it would in these scenarios.
So my quesiton for you is, is my understanding of the expected behavior correct, or am I somehow misusing the event framework?
Or let me know if you require additional configuration information or examples.
Thanks!
--dircha