java - JPA从反面删除双向关联

标签 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,并将所有具有该状态的客户设置为 NULL。

更新

如果没有 preRemove 方法,我会遇到 MySQLIntegrityConstraintViolationException:无法删除或更新父行:外键约束失败

最佳答案

当您迭代客户集合时,无法调用 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); 
    }
}

关于java - JPA从反面删除双向关联,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13687613/

相关文章:

java - 如何将 SIGINT 信号从 Java 发送到外部进程?

java - 如何在 Android 应用程序中下载功能模块?

java - querydsl 是否受到与 JPA Criteria API 相同的限制?

hibernate - 在 EclipseLink 中映射列名和表名

eclipselink - JPA criteria查询元组onetomany join

JavaScript 匿名函数数组到 Java 的翻译

java - 如何将 Java 双冒号运算符 (::) 翻译成 Scala?

java - 具有用于构建实体的内部类的实体

java - 扩展增删改查存储库时如何使用自己的查询进行保存操作?

jpa - EclipseLink 创建表时控制列顺序