I want to write a history component that tracks changes to a particular object type and writes history rows based on the difference. Note this is not a general audit system it is specific for one object type.
I figure I can hook into the hibernate event model and listen for events that tells me when things have changed, watch for any changes to instances of the object type I am interested in, and then have some custom code generate the history rows.
I want the history rows written in the same transaction, and ideally using hibernate (therefore using the same Session)
I have some questions/concerns
Any help appreciated.
There is a generic audit solution for hibernate entities, called envers, that should do the trick.
However, if this solution is not enough (as your comment suggests), the org.hibernate.events package defines the usable events. In you case, I would suggest to implement at least the PostUpdateEventListener interface.
pre-update events seem a good choice.
PreUpdateEvent have a
getSession() method which is:
the session event source for this event. This is the underlying session from which this event was generated.
So, using it, you can create new objects and persist them within the same session and transaction.
When using the these events make sure that you do not touch the session that caused the events to fire. Get the session and retrieve the session factory and open a new session. This will still be in the same transaction, but you will avoid a lot of Hibernate problems.
Also, if you start traversing object graphs on the object that caused the event to fire, then you can get strange errors as you have changed collection states during a flush. There are Jira tickets open for this "bug".