У меня проблемы с настройкой JPA / Hibernate (3.5.3), где у меня есть сущность, класс "Account", в котором есть список дочерних сущностей, экземпляры "Contact". Я пытаюсь добавить / удалить экземпляры Контакта в свойство List учетной записи.
Добавление нового экземпляра в набор и вызов saveOrUpdate (account) сохраняют все прелести. Если я затем решу удалить контакт из списка и снова вызвать saveOrUpdate, похоже, что SQL Hibernate включает в себя установку для столбца account_id значения null, что нарушает ограничение базы данных.
Что я делаю не так?
Приведенный ниже код явно упрощенный реферат, но я думаю, что он охватывает проблему, поскольку я вижу одинаковые результаты в другом коде, который на самом деле примерно такой простой.
SQL:
CREATE TABLE account ( INT account_id );
CREATE TABLE contact ( INT contact_id, INT account_id REFERENCES account (account_id) );
Java:
@Entity
class Account {
@Id
@Column
public Long id;
@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true)
@JoinColumn(name = "account_id")
public List<Contact> contacts;
}
@Entity
class Contact {
@Id
@Column
public Long id;
@ManyToOne(optional = false)
@JoinColumn(name = "account_id", nullable = false)
public Account account;
}
Account account = new Account();
Contact contact = new Contact();
account.contacts.add(contact);
saveOrUpdate(account);
// some time later, like another servlet request....
account.contacts.remove(contact);
saveOrUpdate(account);
Результат:
UPDATE contact SET account_id = null WHERE contact_id = ?
Редактировать # 1:
Может быть, это на самом деле ошибка
http://opensource.atlassian.com/projects/hibernate/browse/HHH-5091
Редактировать # 2:
У меня есть решение, которое, кажется, работает, но использует Hibernate API
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<Contact> contacts = new HashSet<Contact>();
}
class Contact {
@ManyToOne(optional = false)
@JoinColumn(name = "account_id", nullable = false)
private Account account;
}
Поскольку Hibernate CascadeType.DELETE_ORPHAN устарел, я должен предположить, что он был заменен версией JPA2, но в реализации чего-то не хватает.