Hibernate级联更新到集合的对象中没有改变

时间:2012-11-07 14:54:13

标签: hibernate jpa cascade hibernate-cascade

使用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只是将分离的对象与会话重新关联。

菲尔

1 个答案:

答案 0 :(得分:0)

我无法找到一个好的解决方案,因此我最终将ContactSet存储在公司和Salesman中,并从Salesman-&gt; ContactSet中删除所有级联。现在我只需要保存一个新的公司,并保存所有新的ContactSet。在某些情况下,必须更新所有销售员的联系人信息,这只能通过保存所有销售人员的公司来解决(据我所知)。

如果有人找到更好的解决方案,请添加!