Я испытываю затруднения из-за JPA/Hibernate (3.5.3) установка, где у меня есть объект, класс "Учетной записи", который имеет список дочерних объектов, экземпляров "Контакта". Я пытаюсь смочь добавить/удалить экземпляры Контакта в свойство Добавление нового экземпляра в набор и вызов saveOrUpdate (учетная запись) сохраняют все прекрасное. Если я затем принимаю решение удалить контакт из списка и снова назвать saveOrUpdate, SQL В спящем режиме, кажется, производит, включает установку в NULL account_id столбца, который нарушает ограничение базы данных. Что я делаю неправильно? Код ниже является ясно упрощенным кратким обзором, но я думаю, что он покрывает проблему, поскольку я вижу те же результаты в другом коде, который действительно является об этом простом. SQL: Java: Результат: Редактирование № 1: Могло бы случиться так, что это - на самом деле ошибка http://opensource.atlassian.com/projects/hibernate/browse/HHH-5091 Редактирование № 2: У меня есть решение, которое, кажется, работает, но включает использование Быть в спящем режиме API С тех пор В спящем режиме CascadeType. DELETE_ORPHAN удерживается от использования, я должен предположить, что он был заменен версией JPA2, но реализация испытывает недостаток в чем-то.CREATE TABLE account ( INT account_id );
CREATE TABLE contact ( INT contact_id, INT account_id REFERENCES account (account_id) );
@Entity
class Account {
@Id
@Column
public Long id;
@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true)
@JoinColumn(name = "account_id")
public List
UPDATE contact SET account_id = null WHERE contact_id = ?
class Account {
@SuppressWarnings("deprecation")
@OneToMany(cascade = CascadeType.ALL, mappedBy = "account")
@Cascade(org.hibernate.annotations.CascadeType.DELETE_ORPHAN)
@JoinColumn(name = "account_id", nullable = false)
private Set
Некоторые примечания:
mappedBy
для объявления стороны-владельца ассоциации. равно
и hashCode
в контакте
. Итак, в Аккаунте
измените отображение следующим образом:
@Entity
public class Account {
@Id @GeneratedValue
public Long id;
@OneToMany(cascade = CascadeType.ALL, mappedBy = "account", orphanRemoval = true)
public List<Contact> contacts = new ArrayList<Contact>();
public void addToContacts(Contact contact) {
this.contacts.add(contact);
contact.setAccount(this);
}
public void removeFromContacts(Contact contact) {
this.contacts.remove(contact);
contact.setAccount(null);
}
// getters, setters
}
В Контакт
важная часть состоит в том, что в поле @ManyToOne
должно быть указано необязательный
флаг установлен на false
:
@Entity
public class Contact {
@Id @GeneratedValue
public Long id;
@ManyToOne(optional = false)
public Account account;
// getters, setters, equals, hashCode
}
С этими изменениями работает следующее:
Account account = new Account();
Contact contact = new Contact();
account.addToContact(contact);
em.persist(account);
em.flush();
assertNotNull(account.getId());
assertNotNull(account.getContacts().get(0).getId());
assertEquals(1, account.getContacts().size());
account.removeFromContact(contact);
em.merge(account);
em.flush();
assertEquals(0, account.getContacts().size());
И потерянный Контакт
удаляется, как и ожидалось. Протестировано с Hibernate 3.5.3-Final.