views:

349

answers:

1

I have a JPA annotated class which contains a collection like so:

@Entity
public class Employee {
    @Id
    private int id; 
    @Basic
    private String name;    
    @OneToMany
    @JoinTable(name = "ORG", joinColumns = @JoinColumn(name="MINION"),
  inverseJoinColumns = @JoinColumn(name="EMP"))
    private List<Employee> minions = new ArrayList<Employee>();

    @PreUpdate
    public void preUpdate(){ ... }
}

What I'm seeing is that if I have a managed Employee entity and I add to it's collection of minions the preUpdate method is not getting invoked. A new row is added to the mapping table in the DB so I know the update is going through. If I change a property directly on the Employee, like name, then preUpdate fires as expected when the transaction is committed.

Is there a way to get PreUpdate to fire when a mapped collection is modified? Or is there some other technique or Hibernate specific annotation for detecting when this happens?

+1  A: 

@PreUpdate event is triggered just before database UPDATE operation is executed for the entity in question.

If you're not updating direct properties of Employee, there's no UPDATE to execute for its table and thus @PreUpdate listener is never called. You should have better luck using @PrePersist event which is triggered by "flush" rather than "update".

ChssPly76
You're correct. PrePersist doesn't help either since it is fired on INSERT and in this case the collection is modified after the entity has already been persisted. I guess my question is really asking if there are techniques that function similar to PreUpdate to detect when a mapped collection is modified.
Adam B
I'm not sure what you mean by "fired on INSERT". Aren't you calling `entityManager.persist(employee)` to save your collection? If you're not (e.g. you're relying on flush _only_) you're going to have to configure your own listener for one (or more) of "flush" / "auto-flush" / "flush-entity" events (http://docs.jboss.org/hibernate/stable/entitymanager/reference/en/html/configuration.html#d0e500). Or, for a Hibernate-specific solution, write your own interceptor (http://docs.jboss.org/hibernate/stable/core/reference/en/html/events.html#objectstate-interceptors) - onFlushDirty() is always called
ChssPly76