使用Hibernate 3.3,JPA 1.x和Hsqldb 1.8
我遇到了对包含其他对象集合的对象进行级联更新的问题。这是一个人为的(略)示例(省略了getters / setters)。对不起它的代码很多,我找不到另一种方式来表达这个问题,而且这一切都很简单。
@Entity
public class Salesman
{
@Id
@GeneratedValue
@Column(name="salesman_id")
private long id;
@OneToMany(mappedBy=salesman, targetEntity=ContactSet.class, fetch=FetchType.EAGER, cascade=CascadeType.All)
private Set<ContactSet> contacts;
}
@Entity
public class Company
{
@Id
@GeneratedValue
@Column(name="company_id")
private long id;
@Column(name="company_name")
private String name;
}
@Entity
public class ContactSet
{
@Id
@GeneratedValue
@Column(name="contact_set_id")
private long id;
@ManyToOne(fetch=FetchType.EAGER)
@JoinColumn(name="salesman_id",referencedColumnName="salesman_id", updatable=false, nullable=false)
private Salesman salesman
@ManyToOne
@JoinColumn(name="company_id", referencedColumnName="company_id", updatable=false, nullable=false)
private Company company;
@OneToMany(mappedBy="contactSet", targetEntity=Contact.class, fetch=FetchType.EAGER, cascade=CascadeType.ALL)
private Set<Contact> contacts;
}
@Entity
public class Contact
{
@Id
@GeneratedValue
@Column(name="contact_id")
private long id;
@ManyToOne(fetch=FetchType.EAGER)
@JoinColumn(name="contact_set_id",referencedColumnName="contact_set_id", updatable=true, nullable=false)
private ContactSet contactSet;
@Column(name="contact_name", updatable=false, nullable=false)
private String name;
}
因此,销售人员为每家公司提供一组联系人,并且可能有许多销售人员为公司提供服务,每个公司都有不同的联系人。我可以向销售人员添加新公司(及相关联系人),一切都很好。
将新公司(和联系人)添加到已经有一些的销售人员时会出现问题:
session.beginTransaction();
session.lock(salesman, LockMode.NONE)
ContactSet newSet = new ContactSet();
/*...Add contacts to ContactSet...*/
salesman.addContactSet(newSet);
session.saveOrUpdate(salesman);
session.commit();
当使用hibernate.show_sql = true运行它时,我可以看到这具有为每个Contact运行Insert的预期效果,并插入新的ContactSet。我还看到了Salesman本身的更新,以及有问题的销售人员所有其他ContactSet和Contact的更新。由于每个销售人员有数千个联系人,因此此交易需要很长时间。
我的问题是,如何避免我知道没有更改的ContactSet和联系人的所有更新?我尝试添加@Version标签,更改CascadeType(除了我的应用程序中的所有功能都失败)和更多特定代码的修补,但没有成功!
提前感谢任何指示,
**编辑:发现将event.lock(salesman,LockMode.NONE)添加到事务意味着其他对象不会更新,但代码仍然很慢。我怀疑是因为它仍然在会话中添加了数千个对象来锁定它们。更新了示例代码以反映这一点。 LockMode.NONE只是将分离的对象与会话重新关联。
菲尔
答案 0 :(得分:0)
我无法找到一个好的解决方案,因此我最终将ContactSet存储在公司和Salesman中,并从Salesman-&gt; ContactSet中删除所有级联。现在我只需要保存一个新的公司,并保存所有新的ContactSet。在某些情况下,必须更新所有销售员的联系人信息,这只能通过保存所有销售人员的公司来解决(据我所知)。
如果有人找到更好的解决方案,请添加!