Hibernate version: 3.1.3
Database: PostgreSQL 8.1.4
Hello,
Our object model is similar to the composite pattern (Class Xyz contains references to other Xyz), and we would like to configure a save/insert listener so that the listener runs for each instance in an object graph.
(My main question is below, however).
Domain model Example:
Code:
public class Xyz {
private Long id;
private Xyz specialMember;
private Collection<Xyz> memberCollection;
private User primaryAssignee;
private Collection<User> assignedUsers;
// ...etc.
}
In the example above when an Xyz instance is saved, e.g.
Code:
session.save(myXyz);
I would like the listener to run once on the myXyz instance, and once on each contained instance of Xyz.
My (limited) understanding is that I could use the FlushEntityEventListener or possibly the PreInsertEventListener for certain kinds of changes.
The complication is that we also hope for this listener to modify one or more object references of an Xyz instance. In the example below, I use a temporary session to retrieve a different object that we hope to associate.
Listener example:Code:
public void onFlushEntity(FlushEntityEvent event) throws HibernateException {
String[] propertyNames = event. getEntityEntry().getPersister().getPropertyNames();
Object[] currentState = event.getPropertyValues();
Session currentSession = event.getSession();
Session tempSession = currentSession.getFactory().openSession(currentSession.connection());
//Retrieving arbitrary user for example
User newAssignee = tempSession.get(User.class, new Long(27));
for ( int i=0; i<propertyNames.length; i++ ) {
if ("primaryAssignee".equals(propertyNames[i]) ) {
currentState[i] = newAssignee;
} else if ("assignedUsers".equals(propertyNames[i]) ) {
Collection assignees = currentState[i];
assignees.add(newAssignee);
}
}
}
My main question is whether it is possible to make a change within a listener (e.g. to a collection or another persistent object reference) that will be picked up by hibernate,
if the current save operation has already been cascaded, as it would have to be in order for this listener to run on all instances of class Xyz.
My secondary question is whether it would be necessary (and possible) to re-attach a managed object to the main session within the listener; i.e. would I have to re-attach the newAssignee in the example above before associating it with the currentState of the persistent object? Is this allowed?
I think that related to this might be that I am somewhat unclear on the differences in the EventListener contract between FlushEntityEvent.entity and FlushEntityEvent.propertyValues.
Thanks for any help or perhaps recommendations on other approaches to modifying persistent object references within a listener or an interceptor.
Kind regards. --Dan