【问题标题】:JPA (with Play!) bidirectional Many-to-Many - how to remove from both sides of the relationship?JPA(with Play!)双向多对多-如何从关系的双方中删除?
【发布时间】:2011-05-18 13:04:16
【问题描述】:

我的 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();
}

【问题讨论】:

    标签: jpa many-to-many constraints playframework cascading-deletes


    【解决方案1】:

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-12-31
      • 2011-03-29
      • 1970-01-01
      • 2016-09-10
      • 1970-01-01
      • 2017-11-11
      相关资源
      最近更新 更多