JPA2 Lazy Child Collection 与 orphanRemoval=true 删除“未获取”;孩子们

发布于 2024-11-19 15:16:05 字数 1883 浏览 2 评论 0原文

我有一个父实体,它拥有(通过mappedBy)FetchType.LAZY Set;与 orphanDelete=true。

客户端可以愉快地通过父级的集合 getter 添加和删除子行,并且它们的更改在 em.merge(parent) 之后正确提交。

但是,如果客户端合并父集合而不访问子集合,则所有子行都会在父集合提交时被删除。

OpenJPA 2.1.0 和 2.1.1-20110610.205956-18 快照二进制文件下也表现出相同的行为。

任何指示将不胜感激。

举例说明:

@Entity
public class Parent{

    @Column
    private String name;

    @OneToMany(mappedBy="parent", fetch=LAZY, cascade = ALL, orphanRemoval=true)
    private Set<Child> children;

    public String getName(){return name;}
    public void setName(String name){this.name=name;}

    public Set<Child> getChildren(){
        return children;
    }
}

@Entity
public class Child{

    @ManyToOne(optional = false, targetEntity = Parent.class)
    @JoinColumn(name="parent_id", nullable=false)
    private Parent parent;

}

两个实体都声明了 @Id 和 @Version 属性,并实现了适当的 hashCode、equals 和 CompareTo 方法。

以下客户端代码完美运行,更新了parent.name,插入了1个子级,删除了1个子级

EntityTransaction eTx=em.getTransaction();
eTx.begin();

Parent par=em.find(Parent.class, parId);
    //PersistenceUnitUtil.isLoaded(par) returns true
    //PersistenceUnitUtil.isLoaded(par, "children") returns false
Collection<Child> children=par.getChildren();
    //PersistenceUnitUtil.isLoaded(par, "children") returns true
Child child = children.iterator().next();
par.getChildren().remove(child);
par.getChildren().add(new Child(par, "I'm New"));
par.setName("I am Updated");
par=em.merge(par);

eTx.commit();

以下代码将为每个父级的子级发出删除命令:

EntityTransaction eTx=em.getTransaction();
eTx.begin();

Parent par=em.find(Parent.class, parId);
   //PersistenceUnitUtil.isLoaded(par) here returns true, and
   //PersistenceUnitUtil.isLoaded(par, "children") returns false
par.setName("I am Updated");
par=em.merge(par);
eTx.commit();

I have a Parent entity that owns(via mappedBy) a FetchType.LAZY Set<Child> with orphanDelete=true.

A client can happily add and remove child rows via the parent's collection getter and their changes are properly committed after an em.merge(parent).

However, if a client merges a parent WITHOUT accessing the child collection, all child rows are deleted on the parent's commit.

The same behavior is exhibited under OpenJPA 2.1.0 and the 2.1.1-20110610.205956-18 snapshot binary.

Any pointers would be appreciated.

An example to illustrate:

@Entity
public class Parent{

    @Column
    private String name;

    @OneToMany(mappedBy="parent", fetch=LAZY, cascade = ALL, orphanRemoval=true)
    private Set<Child> children;

    public String getName(){return name;}
    public void setName(String name){this.name=name;}

    public Set<Child> getChildren(){
        return children;
    }
}

@Entity
public class Child{

    @ManyToOne(optional = false, targetEntity = Parent.class)
    @JoinColumn(name="parent_id", nullable=false)
    private Parent parent;

}

Both entities have @Id and @Version properties declared and implement appropriate hashCode, equals and compareTo methods.

The following client code works perfectly, the parent.name is updated, 1 child is inserted and 1 child is deleted

EntityTransaction eTx=em.getTransaction();
eTx.begin();

Parent par=em.find(Parent.class, parId);
    //PersistenceUnitUtil.isLoaded(par) returns true
    //PersistenceUnitUtil.isLoaded(par, "children") returns false
Collection<Child> children=par.getChildren();
    //PersistenceUnitUtil.isLoaded(par, "children") returns true
Child child = children.iterator().next();
par.getChildren().remove(child);
par.getChildren().add(new Child(par, "I'm New"));
par.setName("I am Updated");
par=em.merge(par);

eTx.commit();

The following code will issue delete commands for each of the parent's children:

EntityTransaction eTx=em.getTransaction();
eTx.begin();

Parent par=em.find(Parent.class, parId);
   //PersistenceUnitUtil.isLoaded(par) here returns true, and
   //PersistenceUnitUtil.isLoaded(par, "children") returns false
par.setName("I am Updated");
par=em.merge(par);
eTx.commit();

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

浅听莫相离 2024-11-26 15:16:06

只是不要调用合并。没有必要。在事务范围内,对该事务中查找的对象所做的更改将被持久化,除非该对象被分离。

Just don't call merge. There's no need for it. Within the scope of a transaction, changes made to an object that was looked up within that transaction will be persisted unless the object is detached.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文