我有一个JPA /休眠(3.5.3)的设置,在这里我有一个实体,一个“账户”类,它有子实体,“联系人”实例的列表麻烦。我想能够添加/删除联系人的情况下,进入名单<联系人账户的>财产。休眠触发约束违规使用orphanRemoval
添加一个新的实例进入设置和调用saveOrUpdate(账户)持续一切可爱。如果我然后选择从列表中删除联系人并再次调用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:
我有,似乎工作的解决方案,但包括使用
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;
}
由于休眠CascadeType.DELETE_ORPHAN已过时,我不得不在Hibernate API假设它已经被JPA2版本所取代,但是实现缺乏一些东西。
我认为是什么让这件事情起作用,@JoinColumn上的选项nullable = false,@ManyToOne上的选项= false,而不是自定义的hibernate级联。 – Thierry 2010-06-18 13:21:22
即使我添加了可空和可选标志,它仍然失败,但是这次它意识到它创建了一个它违反了注释约束的场景,而不是SQL。看起来,3.5.3和JPA2可能仍然是一些问题,因为我无法让@ElementCollection表现得很好。 – ptomli 2010-06-18 13:30:06
将CascadeType设置为ALL将执行所有不需要显式指定的操作DELETE_ORPHAN – 2013-04-17 12:57:02