Java 添加到集合时不触发预更新
我有一个JPA注释类,其中包含如下集合: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
@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语句,因此在任何情况下都可以确定确切需要哪个导入。在这种情况下,我有你从哪里得到的反光片。现在,我认为许多第三方库都包含了一个类caledReflectionUtils