Improve Memory Management when Post Commit Listeners are enabled
Description
Attachments
1
- 25 Apr 2009, 12:59 AM
depends on
is fixed by
Activity
Show:

Shawn ClowaterAugust 19, 2012 at 3:17 AM
Steve, you have made me a very happy man, I've been procrastinating making that change myself. That's exactly what I've been looking for.
Steve EbersoleAugust 19, 2012 at 2:05 AM
I changed the listener interfaces for the listeners involved. E.g.:
public interface PostInsertEventListener extends Serializable {
...
/**
* Does this listener require that after transaction hooks be registered? Typically this is {@code true}
* for post-insert event listeners, but may not be, for example, in JPA cases where there are no callbacks defined
* for the particular entity.
*
* @param persister The persister for the entity in question.
*
* @return {@code true} if after transaction callbacks should be added.
*/
public boolean requiresPostCommitHanding(EntityPersister persister);
}
I adjusted the standard JPA and Envers implementations of these listeners to do the right thing. With custom listeners you will have to do the same. The idea though is that if any post-commit listeners for a given type of entity and type of callback return true the AfterTransactionCompletionProcess gets registered.

Shawn ClowaterAugust 19, 2012 at 1:36 AM
Steve, is the fix only when using JPA?
Steve EbersoleAugust 18, 2012 at 11:06 PM
BTW, this is resolved under https://hibernate.atlassian.net/browse/HHH-7387#icft=HHH-7387
Steve EbersoleApril 18, 2011 at 6:09 PM
It will actually likely be beta1 but I have not set up that version yet...
Out of Date
Details
Assignee
UnassignedUnassignedReporter
Shawn ClowaterShawn ClowaterComponents
Priority
Major
Details
Details
Assignee
Unassigned
UnassignedReporter

Components
Priority
Created March 10, 2009 at 12:13 AM
Updated August 19, 2012 at 3:17 AM
Resolved August 18, 2012 at 11:06 PM
This is somewhat related to the QueryCache behavior reported under http://opensource.atlassian.com/projects/hibernate/browse/HHH-3028
In this particular case however, it is the fact that when the session factory is configured to have post commit listeners it prevents the garbage collection of any entity that is modified during the session due to the fact that it is referenced in the executions list in the ActionQueue class. This makes any type of memory management by flushing/clearing the session ineffective if you're in the middle of a large batch that is inserting or updating a large amount of data.
i.e in our case we have 4 entities out of possibly 300 or so that we want to notify external systems if they change. However, by simply having the listeners defined they essentially block the remaining entities in the executions.
A potential workaround I guess might be to keep 2 session factories around with a different set of listeners but that seems a bit dirty.
There are 2.5 potential ways that I can think of that might address this.
1 - Have some sort of flag on the session to disable the post commit listeners. The onus would be on the user of the session to disable the listeners in the case where they know they aren't modifying anything that will need post commit handling.
2 - Add the ability to configure the post commit listeners by entity
a)With polymorphism - i.e. you could add a listener based on Object.class and it would apply to all entities and would behave much like it does now. You could also configure to Animal.class and would include Cat and Dog.
b)Without polymorphism - you could add a listener based on a specific entity class and it would only apply to that particular one. You would have an option to specify a null entity and it would default to what is there today.
In my miind, 2a is probably the best albeit slightly more complex to implement but I think would be a good value add.
I don't mind submitting a patch assuming that I'm not so far in left field that I should be committed.