我在JPA/Hibernate(3.5.3)的设置中遇到了问题,我有一个实体,一个“Account”类,它有一个子实体列表,“Contact”实例。我正在尝试将联系人实例添加/删除到列表中<联系方式>账户财产。
将一个新实例添加到集合中并调用saveOrUpdate(account)会保持一切。如果然后选择从列表中删除联系人并再次调用saveOrUpdate,那么SQL Hibernate似乎会将account\u id列设置为null,这违反了数据库约束。
我做错什么了?
下面的代码显然是一个简化的抽象,但我认为它涵盖了这个问题,因为我在不同的代码中看到了相同的结果,这确实是关于这个简单的问题。
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<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:
可能这实际上是一个bug
http://opensource.atlassian.com/projects/hibernate/browse/HHH-5091
编辑#2:
我有一个似乎可行的解决方案,但涉及到使用hibernateapi
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\u ORPHAN已被弃用,我不得不假设它已被JPA2版本取代,但实现中缺少一些东西。