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?
@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".
Maybe a this custom workaround works:
Create a subclass of ArrayList which identifies changes through ActionListener pattern
public class Employee {
....
private List<Employee> minions = createChangeNotifierList();
private List<Employee> createChangeNotifierList() {
ChangeNotifierList<Employee> l = new ChangeNotifierList<Employee>();
l.setActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
preUpdate();
}
});
return l;
}
public void setMinions(List<Employee> l) {
if (!(l instanceof ChangeNotifierList)) {
l = createChangeNotifierList();
preUpdate();
}
this.minions = l;
}
public void preUpdate(){ ... }
}
public class ChangeNotifierList<T> extends ArrayList<T> {
private ActionListener actionListener;
public ChangeNotifierList() {
}
public ChangeNotifierList(List<T> list) {
super.addAll(list);
}
public void setActionListener(ActionListener actionListener) {
this.actionListener = actionListener;
}
public boolean add(T e) {
boolean b = super.add(e);
if (b) {
notifyChange();
}
return b;
}
private void notifyChange() {
actionListener.actionPerformed(null);
}
.....
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With