JPA(带Play!)双向多对多-如何删除双方的关系?

发布于 2024-11-08 16:20:48 字数 1919 浏览 0 评论 0原文

我的 Play 中有以下映射!使用 JPA 的应用程序:

@Entity
public class Contact extends Model {        
    public String name;

    @ManyToMany(mappedBy = "contacts", fetch = FetchType.EAGER)
    public Set<Category> categories = new HashSet<Category>();

    public void addCategory(Category c) {
        this.categories.add(c);
        if (!c.contacts.contains(this)) {
            c.contacts.add(this);
        }
    }

    @PreRemove
    public void preRemove() {
        for (Category c : this.categories) {
            c.contacts.remove(this);
        }
        this.categories = null;
    }
}

@Entity
public class Category extends Model {
    public String name;

    @ManyToMany
    public Set<Contact> contacts = new HashSet<Contact>();

    public void addContact(Contact c) {
        this.contacts.add(c);
        if (!c.categories.contains(this)) {
            c.categories.add(this);
        }
    }

    @PreRemove
    protected void preRemove() {
        for (Contact c : this.contacts) {
            c.categories.remove(this);
        }
        this.contacts = null;
    }
}

删除类别工作正常,关系已正确更新。但是,如果我删除联系人,则会违反约束条件:

Caused by: org.h2.jdbc.JdbcBatchUpdateException: Referential integrity constraint violation: "FK34B085DF487AF903: 
PUBLIC.CATEGORY_CONTACT FOREIGN KEY(CONTACTS_ID) REFERENCES PUBLIC.CONTACT(ID)"; SQL statement:
delete from Contact where id=? [23003-149]

如何确保删除联系人不会删除类别,而只会删除关系?

编辑:呃!问题是我还有一个用户对象,它引用了联系人和类别。我错过了清理这种关系的机会。以下是 Contact 类中 preRemove() 方法的更改:

@PreRemove
public void preRemove() {
    for (Category c : this.categories) {
        c.contacts.remove(this);
    }

    this.user.contacts.remove(this);
    for (Category c : this.user.categories) {
        c.contacts.remove(this);
    }
    //It's important to save the user 
    this.user.save();
}

I have the following mapping in my Play! app using JPA:

@Entity
public class Contact extends Model {        
    public String name;

    @ManyToMany(mappedBy = "contacts", fetch = FetchType.EAGER)
    public Set<Category> categories = new HashSet<Category>();

    public void addCategory(Category c) {
        this.categories.add(c);
        if (!c.contacts.contains(this)) {
            c.contacts.add(this);
        }
    }

    @PreRemove
    public void preRemove() {
        for (Category c : this.categories) {
            c.contacts.remove(this);
        }
        this.categories = null;
    }
}

@Entity
public class Category extends Model {
    public String name;

    @ManyToMany
    public Set<Contact> contacts = new HashSet<Contact>();

    public void addContact(Contact c) {
        this.contacts.add(c);
        if (!c.categories.contains(this)) {
            c.categories.add(this);
        }
    }

    @PreRemove
    protected void preRemove() {
        for (Contact c : this.contacts) {
            c.categories.remove(this);
        }
        this.contacts = null;
    }
}

Deleting Category works fine, the relationship is updated correctly. If I delete a Contact however, I'm getting a constraint violation:

Caused by: org.h2.jdbc.JdbcBatchUpdateException: Referential integrity constraint violation: "FK34B085DF487AF903: 
PUBLIC.CATEGORY_CONTACT FOREIGN KEY(CONTACTS_ID) REFERENCES PUBLIC.CONTACT(ID)"; SQL statement:
delete from Contact where id=? [23003-149]

How can I ensure that deleting a Contact will not delete the Category but will only remove the relationship?

EDIT: Duh! The issue was I also had a User object which had references to both Contact and Category. I missed clearing that relationship. The following is the change to preRemove() method in Contact class:

@PreRemove
public void preRemove() {
    for (Category c : this.categories) {
        c.contacts.remove(this);
    }

    this.user.contacts.remove(this);
    for (Category c : this.user.categories) {
        c.contacts.remove(this);
    }
    //It's important to save the user 
    this.user.save();
}

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

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

发布评论

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

评论(1

三五鸿雁 2024-11-15 16:20:48

另一种解决方案是在删除主实体之前手动从列表中删除元素并保存它:

while( !contact.categories.isEmpty() ) {  
    contact.categories.remove(0);  
}  
contact.save();  
contact.delete();

An other solution is to manually remove elements from the list and save it, before deleting the main entity :

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