Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/367.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 添加到集合时不触发预更新_Java_Hibernate_Orm_Jpa - Fatal编程技术网

Java 添加到集合时不触发预更新

Java 添加到集合时不触发预更新,java,hibernate,orm,jpa,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(n

我有一个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(){ ... }
}
@实体
公营雇员{
@身份证
私有int-id;
@基本的
私有字符串名称;
@独身癖
@JoinTable(name=“ORG”,joinColumns=@JoinColumn(name=“MINION”),
inverseJoinColumns=@JoinColumn(name=“EMP”))
private List minions=new ArrayList();
@预更新
public void preUpdate(){…}
}
我看到的是,如果我有一个托管员工实体,并且我将其添加到它的仆从集合中,
preUpdate
方法不会被调用。数据库中的映射表中添加了一个新行,因此我知道更新正在进行。如果我直接更改员工的属性,如name,则提交事务时,
preUpdate
将按预期触发


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

@PreUpdate
事件在对相关实体执行之前被触发


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

此自定义解决方案可能会起到以下作用:

创建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);
    }

    .....
}
公共类员工{
....
私有列表minions=createChangeNotifierList();
私有列表createChangeNotifierList(){
ChangeNotifierList l=新的ChangeNotifierList();
l、 setActionListener(新ActionListener(){
已执行的公共无效操作(操作事件e){
预更新();
}
});
返回l;
}
公共无效设置仆从(列表l){
如果(!(更改通知列表的l实例)){
l=createChangeNotifierList();
预更新();
}
这个。仆从=l;
}
public void preUpdate(){…}
}
公共类ChangeNotifierList扩展了ArrayList{
私有ActionListener ActionListener;
公共变更通知列表(){
}
公共变更通知列表(列表){
super.addAll(列表);
}
public void setActionListener(ActionListener ActionListener){
this.actionListener=actionListener;
}
公共布尔加法(TE){
布尔b=超级加法(e);
如果(b){
notifyChange();
}
返回b;
}
私有void notifyChange(){
actionListener.actionPerformed(空);
}
.....
}

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


通常,您只需使用@PreCollectionChange annotation标记脏集合时应调用的方法。

您是正确的。PrePersist也没有帮助,因为它是在INSERT时触发的,在本例中,集合是在实体已被持久化之后修改的。我想我的问题是,是否有类似于PreUpdate的技术可以检测映射集合何时被修改。我不确定“插入时触发”是什么意思。您是否正在调用
entityManager.persist(employee)
保存您的收藏?如果您没有(例如,您仅依赖于flush),则必须为一个(或多个)“flush”/“auto flush”/“flush entity”事件()配置您自己的侦听器。或者,对于特定于Hibernate的解决方案,编写您自己的拦截器()-onFlushDirty()始终被称为duse@Version-请注意,最好包含import语句,因此在任何情况下都可以确定确切需要哪个导入。在这种情况下,我有你从哪里得到的反光片。现在,我认为许多第三方库都包含了一个类caled
ReflectionUtils