我正在使用JPA 2.0和Hibernate 4.1.0.Final。我有这个实体(用户和地址对象之间的单向关系)......
@Entity
@Table(name = "user")
public class User implements Serializable
{
@OneToMany(fetch = FetchType.EAGER, cascade = {CascadeType.ALL}, orphanRemoval=true)
@JoinTable(name = "user_address", joinColumns = @JoinColumn(name = "user_id"), inverseJoinColumns = @JoinColumn(name = "address_id"))
private Set<Address> addresses;
在我的“updateUser”方法中,我有这段代码
user.setAddresses(addresses);
调用
public void setAddresses(Set<Address> addresses)
{
if (this.addresses == null)
{
this.addresses = new HashSet<Address>();
}
this.addresses.clear();
if (addresses != null)
{
this.addresses.addAll(addresses);
} // if
}
问题是地址仅在“地址”是新对象时保存,而不是重新保存现有地址实体。使用现有地址更新用户需要做什么?
编辑:以下是我如何保存实体...
protected Object save(Object obj)
{
if (obj != null)
{
final Object id = getId(obj);
if (id == null)
{
m_entityManager.persist(obj);
}
else
{
obj = m_entityManager.merge(obj);
} // if
} // if
return obj;
} // save
答案 0 :(得分:2)
为了保存用户和调用session.merge所需的地址:
user.setAddresses(addresses);
session.merge(user);
合并将从User级联到Addresses,它将适用于新实体和分离的实体。
同样清除列表并添加元素也不是很好。我建议做类似的事情:
//always initialize the children ollections
private Set<Address> addresses = new HashSet<Address>();
//make sure equals/hashcode are implemented according to the business key semantics
//don't use the entity id for equals and hashcod
public void setAddresses(Set<Address> addresses) {
//1. remove the existing addresses that are not found in the new ones
this.addresses.retainAll(addresses);
//2. add the new addresses too, the common ones will be ignored by the Set semantics
this.addresses.addAll(addresses);
}
答案 1 :(得分:1)
Collection属性的最佳实践是将集合初始化为一个新的空集合,让Hibernate对其进行代理并以正确的方式管理对象删除。
尝试将代码更改为
@GenericGenerator(name = "uuid-strategy", strategy = "org.collegeboard.springboard.core.util.SpringboardUUIDGenerator")
@Entity
@Table(name = "user")
public class User implements Serializable
{
@OneToMany(fetch = FetchType.EAGER, cascade = {CascadeType.ALL}, orphanRemoval=true)
@JoinTable(name = "user_address", joinColumns = @JoinColumn(name = "user_id"), inverseJoinColumns = @JoinColumn(name = "address_id"))
private Set<Address> addresses = new HashSet<Address>;
另请查看Hibernate @ManyToOne only works with CascadeType.ALL以获取正确的注释/持久性方法对