0

使用 Hibernate 3.3、JPA 1.x 和 Hsqldb 1.8

我在对包含其他对象集合的对象进行级联更新时遇到问题。这是一个人为的(稍微)示例来说明(省略了获取器/设置器)。对不起,它有很多代码,我找不到另一种方式来表达这个问题,而且这里的一切都相当简单。

@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 运行它时,我可以看到这具有为每个联系人运行插入并为新的 ContactSet 插入的预期效果。我还看到了销售员本身的更新,以及有关销售员拥有的所有其他 ContactSet 和 Contact 的更新。由于每个业务员有数千个联系人,因此此交易需要很长时间。

我的问题是,如何避免我知道没有更改的 ContactSets 和 Contacts 的所有更新?我已经尝试添加 @Version 标签,更改 CascadeType(在我的应用程序中除了 ALL 之外的任何东西都失败了)并加载了更具体的代码修补,但没有成功!

在此先感谢您的任何指点,

**编辑:发现添加 session.lock(salesman, LockMode.NONE) 到事务意味着其他对象没有得到更新,但代码仍然很慢。我怀疑是因为它仍在向会话中添加数千个对象以锁定它们。更新了示例代码以反映这一点。LockMode.NONE 只是将分离的对象与会话重新关联。

菲尔

4

1 回答 1

0

我无法找到一个好的解决方案,所以我最终将 ContactSet 以及 Salesman 存储在 Company 中,并从 Salesman->ContactSet 中删除所有级联。现在我只需要保存一个新的 Company,所有新的 ContactSets 都会保存。仍然存在必须更新所有推销员的 ContactSets 的情况,这只能通过保存推销员的所有公司来解决(据我所知)。

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

于 2012-11-16T15:14:56.450 回答