У нас есть три сущности с двунаправленными сопоставлениями «многие ко многим» в «иерархии» A <-> B <-> C, например, так (упрощенно, конечно):
@Entity
Class A {
@Id int id;
@JoinTable(
name = "a_has_b",
joinColumns = {@JoinColumn(name = "a_id", referencedColumnName = "id")},
inverseJoinColumns = {@JoinColumn(name = "b_id", referencedColumnName = "id")})
@ManyToMany
Collection<B> bs;
}
@Entity
Class B {
@Id int id;
@JoinTable(
name = "b_has_c",
joinColumns = {@JoinColumn(name = "b_id", referencedColumnName = "id")},
inverseJoinColumns = {@JoinColumn(name = "c_id", referencedColumnName = "id")})
@ManyToMany(fetch=FetchType.EAGER,
cascade=CascadeType.MERGE,CascadeType.PERSIST,CascadeType.REFRESH})
@org.hibernate.annotations.Fetch(FetchMode.SUBSELECT)
private Collection<C> cs;
@ManyToMany(mappedBy = "bs", fetch=FetchType.EAGER,
cascade={CascadeType.MERGE,CascadeType.PERSIST, CascadeType.REFRESH})
@org.hibernate.annotations.Fetch(FetchMode.SUBSELECT)
private Collection<A> as;
}
@Entity
Class C {
@Id int id;
@ManyToMany(mappedBy = "cs", fetch=FetchType.EAGER,
cascade={CascadeType.MERGE,CascadeType.PERSIST, CascadeType.REFRESH})
@org.hibernate.annotations.Fetch(FetchMode.SUBSELECT)
private Collection<B> bs;
}
Здесь нет концепциисироты - сущности являются «автономными» с точки зрения приложения - и большую часть времени мы будем иметь пригоршню A: s, каждая с парой B: s (некоторые могут быть «общими»среди A: s) и около 1000 C: s, не все из которых всегда «используются» любым B. Мы пришли к выводу, что нам нужны двунаправленные отношения, поскольку всякий раз, когда экземпляр сущности удаляется, все ссылки (записи)в таблицах объединения) тоже должны быть удалены.Это делается следующим образом:
void removeA( A a ) {
if ( a.getBs != null ) {
for ( B b : a.getBs() ) { //<--------- ConcurrentModificationException here
b.getAs().remove( a ) ;
entityManager.merge( b );
}
}
entityManager.remove( a );
}
Если в коллекции, a.getBs()
здесь, содержится более одного элемента, то создается ConcurrentModificationException
.Некоторое время я бился головой, но не могу придумать разумного способа удалить ссылки, не вмешиваясь в коллекцию, из-за чего лежит Iterator
злой.
Q1: Как яЯ должен был сделать это, учитывая текущую настройку ORM?(Если вообще ...)
Q2: Есть ли более разумный способ спроектировать OR-отображения, которые позволят JPA (предоставленной в данном случае Hibernate) позаботиться обо всем.Было бы просто здорово, если бы нам не пришлось включать эти I'll be deleted now, so everybody I know, listen carefully: you don't need to know about this!
-циклы, которые все равно не работают, как есть ...