У меня двунаправленное отношение «многие ко многим», для которого я пытаюсь добавить новые объекты. После поиска существующих сущностей и добавления их к новой сущности на другой стороне отношения я получаю исключение отсоединенной сущности.
- сохранить адрес (a1) с сотрудниками (e1, e2).
- создать адрес (a2) с сотрудниками (e1, e3)
- поиск в таблице сотрудников и замена ссылки (a2.e1) на существующую сущность сотрудника из базы данных.
- сохранить (a2)
- исключение отдельного объекта
Добавление аннотации таблицы соединений к обеим сторонам, полное удаление обратной ссылки у сотрудников или использование тега оптимистической блокировки не спасет сотрудников при сохранении адресов. Слияние сотрудников до вызова метода @transactional не имеет видимого эффекта.
@Table(name = "addresses")
public class Address {
...address stuff...
@ManyToMany(cascade = CascadeType.Persist, fetch = FetchType.LAZY)
@JoinTable(name = "address_employee",
joinColumns = {@JoinColumn(name = "address_id")},
inverseJoinColumns = {@JoinColumn(name = "employee_id")})
public List<Employee> employees = new ArrayList<>();
}
@Table(name = "employees"
public class Employee {
...employee stuff...
@ManyToMany(mappedBy = "employees")
public Set<Address> addresses = new HashSet<>();
}
public class AddressService {
public Address saveAddress(Address address) {
for (Employee emp : address.getAddresses()) {
Employee dupe = employeeRepo.findByName(emp.getName);
if (dupe != null) {
emp.setId(dupe.getId());
}
}
addressRepo.save(address);
}
}
псевдокодированный тест
public void testMergeEmployees() {
Employee joe = new Employee("Joe");
Address alpha = new Address(joe);
addressService.save(alpha);
Employee joe2 = new Employee("Joe");
Address beta = new Address(joe2);
addressService.save(beta);
// org.hibernate.PersistentObjectException: detached entity passed to persist: com.pseudocode.Employee
assertEquals(1, employeeRepo.findAll().size());
}