简体   繁体   English

防止 Hibernate 对具有脏 OneToMany 集合的实体发出不必要的更新

[英]Prevent Hibernate from issuing needless updates of entities that have dirty OneToMany Collection

We are using Hibernate 5.3.13 with Spring Data JPA 2.1.12 and when having an already persisted, managed minimal Entity like the following:我们将 Hibernate 5.3.13 与 Spring Data JPA 2.1.12 一起使用,并且在已经持久化、托管的最小实体时,如下所示:

@Entity
@Table(name = "EventsHolder")
@Access(AccessType.FIELD)
class EventsHolder {
    @LastModifiedDate
    @Column(name = "modifiedon", nullable = false)
    @Temporal(TIMESTAMP)
    @Access(AccessType.FIELD)
    Date modifiedOn;

    @Version
    @Column(name = "optlock", nullable = false)
    @Access(AccessType.FIELD)
    long optimisticLockingVersion = 0L;

    @Embedded
    Events events = new Events();

that contains the following Embeddable包含以下Embeddable

@Embeddable
@Access(AccessType.FIELD)
class Events {

    @OneToMany(mappedBy = ...)
    @OrderBy("id ASC")
    @BatchSize(size = 10)
    List<Event> events = new LinkedList<>();

Now, whenever calling EventsHolder.events.add(...) with an already persisted, managed event that is added to the collection, hibernate - while doing auto-flushing - will detect the EventsHolder.Events.events collection as being dirty in org.hibernate.event.internal.DefaultFlushEntityEventListener#hasDirtyCollections and will issue (not sure whether this is an important prerequisite here) an Pre-Update call to Spring Data's AuditingHandler which will update the modifiedOn.现在,每当调用EventsHolder.events.add(...)并添加到集合中的已持久托管事件时,hibernate - 在执行自动刷新时 - 将检测EventsHolder.Events.events集合在org.hibernate.event.internal.DefaultFlushEntityEventListener#hasDirtyCollections中是脏的org.hibernate.event.internal.DefaultFlushEntityEventListener#hasDirtyCollections并将发出(不确定这是否是这里的重要先决条件)对 Spring Data 的 AuditingHandler 的更新前调用,这将更新 modifiedOn。

In the end, the optimisticLockingVersion will get incremented and hibernate issues an update statement that basically only updates modified-on and the version.最后,optimisticLockingVersion 将递增并且 hibernate 发出更新语句,基本上只更新修改后的版本和版本。

With EventsHolder that contain 5000 events we see optlock-versions around 4500-5000 and the database's audit-log is thrashed with said "non-updates" that only update modified-on and the optimistic-locking-version.对于包含 5000 个事件的 EventsHolder,我们看到大约 4500-5000 的 optlock-versions 并且数据库的审计日志被所说的“非更新”所困扰,这些“非更新”只更新修改后的版本和乐观锁定版本。

Any idea on how to stop this behaviour very much appreciated.非常感谢任何关于如何阻止这种行为的想法。

by removing the indirection - the embeddable Events that only contained the @OneToMany-field and inlining it directly into the entity - the dirty-check was not continuously detecting the collection as dirty anymore and everything is fine now.通过删除间接 - 仅包含 @OneToMany 字段并将其直接内联到实体中的可嵌入Events - 脏检查不再持续检测集合为脏,现在一切都很好。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM