JPA从反面删除双向关联

时间:2012-12-03 16:32:55

标签: java jpa eclipselink

在我的域模型中有很多双向关联(OneToMany和ManyToMany)

我已阅读this article,并根据样本模式制作了所有关联。 (ManyToMany关联有一个双面的addXY方法,遵循模式)

使用the pattern in this article问题是,如何从反面删除?

示例:

public class Customer implements Serializable {

...

@ManyToOne()
private CustomerStatus customerStatus;


@PreRemove
public void preRemove(){
    setCustomerStatus(null);
}

public void setCustomerStatus(CustomerStatus customerStatus) {
    if(this.customerStatus != null) { this.customerStatus.internalRemoveCustomer(this); }
    this.customerStatus = customerStatus;
    if(customerStatus != null) { customerStatus.internalAddCustomer(this); }
}

另一方面:

public class CustomerStatus implements Serializable {

private static final long serialVersionUID = 1L;

@OneToMany(mappedBy="customerStatus")
private List<Customer> customers;

@PreRemove
public void preRemove(){
    for(Customer c : customers){
        c.setCustomerStatus(null); // this causes ConcurrentException
    }

}

public List<Customer> getCustomers() {
    return Collections.unmodifiableList(this.customers);
}

public void addCustomer(Customer c){
    c.setCustomerStatus(this);
}

public void removeCustomer(Customer c){
    c.setCustomerStatus(null);
}

void internalAddCustomer(Customer c){
    this.customers.add(c);
}

void internalRemoveCustomer(Customer c){
    this.customers.remove(c);
}

问题是,preRemove方法会导致ConcurrentException。怎么办呢? 目标是删除CustomerStatus,并将具有该状态的所有Customers设置为NULL。

更新

如果没有preRemove方法,我已经MySQLIntegrityConstraintViolationException: Cannot delete or update a parent row: a foreign key constraint fails

1 个答案:

答案 0 :(得分:2)

在迭代客户集合时,不能调用this.customers.remove(c)。这个问题之前出现过,所以您可以在这里找到其他解决方案:  How to avoid ConcurrentModificationException when iterating over a map and changing values?

但一个简单的解决方案就是从旧版本创建一个新列表来迭代preRemove:

public void preRemove(){
    List<Customer> tempList = new ArrayList(customers);
    for(Customer c : tempList){
        c.setCustomerStatus(null); 
    }
}