添加到集合时,PreUpdate不会触发

时间:2009-11-23 21:59:42

标签: java hibernate orm jpa

我有一个JPA注释类,其中包含如下所示的集合:

@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(){ ... }
}

我所看到的是,如果我有一个托管的Employee实体,并且我添加了它的minions集合,则不会调用preUpdate方法。在DB中的映射表中添加了一个新行,因此我知道更新正在进行中。如果我直接在Employee上更改属性(如名称),那么preUpdate会在事务提交时按预期触发。

有没有办法在修改映射集合时触发PreUpdate?或者是否有其他技术或Hibernate特定注释用于检测何时发生?

3 个答案:

答案 0 :(得分:6)

@PreUpdate事件是在相关实体执行database UPDATE operation之前触发的。

如果您没有更新Employee的直接属性,则不会为其表执行UPDATE,因此永远不会调用@PreUpdate侦听器。使用由{flush“触发而不是”更新“的@PrePersist事件应该会更好运。

答案 1 :(得分:2)

也许这个自定义解决方法有效:

创建ArrayList的子类,通过ActionListener模式

标识更改
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);
    }

    .....
}

答案 2 :(得分:0)

这是我对Hibernate提供程序的实现:

http://pastebin.com/8cPB96bZ

通常,您只需标记在使用@PreCollectionChange批注的脏集合中应调用的方法。