简体   繁体   中英

JPA deleting bidirectional association from inverse side

In my domain model there are a lot of bidirectional associations (both OneToMany and ManyToMany)

I've read this article and made all my associations on the basis of the sample pattern. (the ManyToMany associations has a two-sided addXY methods, following the pattern)

Using the pattern in this article the question is, what about deleting from the inverse side?

Example:

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); }
}

On the other side:

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);
}

The problem is, that the preRemove method causes ConcurrentException . How to handle this? The goal is, to delete the CustomerStatus, and set NULL all the Customers, where there was that status.

UPDATE

Without the preRemove method, I've got MySQLIntegrityConstraintViolationException: Cannot delete or update a parent row: a foreign key constraint fails

You cannot call this.customers.remove(c) while you are iterating over the customer collection. This question has come up before so you may find other solutions as in here: How to avoid ConcurrentModificationException when iterating over a map and changing values?

but a simple solution is to just create a new list from the old to iterate over on preRemove:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM