如何减少hibernate对级联表的更新查询次数?

时间:2017-06-06 19:28:47

标签: sql performance hibernate

我正在尝试使用Hibernate 4.3来提高应用程序的更新性能。

我有一份人员和城镇的名单,如此

@Table(name = "PERSON", schema = "COUNTY", catalog = "")
@Entity
public class PersonBean{

  @MapsId("town")
  @ManyToOne
  @JoinColumn(name = "TOWN_ID")
  private Long townID;

  @Column(name = "NAME")
  @Basic
  private String personName;

  @Column(name = "UPDATE_DATE")
  @Basic
  private Date updateDate;

  ...
}

...

@Table(name = "TOWNS", schema = "COUNTY")
@Entity
public class TownBean {

    @Column(name = "ID")
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO, generator = "town_id_gen")
    @SequenceGenerator(name = "town_id_gen", sequenceName = "TOWN_SEQ")
    private Long id;

    @Column(name = "NAME")
    @Basic
    private String name;

... (more simple properties) ...

    @OneToMany(fetch = FetchType.LAZY, mappedBy = "people", cascade = CascadeType.ALL, orphanRemoval = true)
    @BatchSize(size = 50)
    private List<PersonBean> people;

只需拨打

即可完成这些项目的更新
repository.saveAndFlush(town);

其中一些城镇相当大,一个城镇的2万人并不罕见。

在DAO和资源中,所有更新都发生在城镇级别......例如,要更改城镇中某个人的名称,您将使用完整的新名称列表输入新的城镇资源。 在数据库中,这需要更新引用该城镇的所有人行以更改updateDate,而Hibernate通过为每个人发出一个更新查询来执行此操作,这可能意味着20,000个查询。 (遗憾的是@BatchSize注释applies only to reading。)这会导致系统性能下降。

我认为我可以通过将repository.saveAndFlush(town)操作替换为打开事务的自定义事务逻辑,使用批处理刷新组中的人员列表,然后写入城镇对象来优化此...

有没有更聪明的方法可以减少Hibernate发送的更新查询数量(通过批处理或其他方式)而不改变系统行为?也许有一些更聪明的方式使用custom SQLNamed Entity Graphs或其他什么?

0 个答案:

没有答案