防止 Hibernate 对具有脏 OneToMany 集合的实体发出不必要的更新
Prevent Hibernate from issuing needless updates of entities that have dirty OneToMany Collection
我们将 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();
包含以下 Embeddable
@Embeddable
@Access(AccessType.FIELD)
class Events {
@OneToMany(mappedBy = ...)
@OrderBy("id ASC")
@BatchSize(size = 10)
List<Event> events = new LinkedList<>();
现在,每当调用 EventsHolder.events.add(...)
并添加到集合中的已持久托管事件时,休眠 - 在执行自动刷新时 - 将检测 EventsHolder.Events.events
集合在 org.hibernate.event.internal.DefaultFlushEntityEventListener#hasDirtyCollections
并将发出(不确定这是否是这里的重要先决条件)对 Spring Data 的 AuditingHandler 的预更新调用,这将更新 modifiedOn。
最后,optimisticLockingVersion 会递增,hibernate 发出更新语句,基本上只更新修改后的版本。
对于包含 5000 个事件的 EventsHolder,我们看到大约 4500-5000 的 optlock-versions 并且数据库的审计日志被所说的 "non-updates" 搅动,只更新修改后的版本和乐观锁定版本。
非常感谢任何关于如何阻止这种行为的想法。
通过删除间接 - 仅包含 @OneToMany 字段并将其直接内联到实体中的可嵌入 Events
- 脏检查不再持续检测集合是否脏,一切都很好现在。
我们将 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();
包含以下 Embeddable
@Embeddable
@Access(AccessType.FIELD)
class Events {
@OneToMany(mappedBy = ...)
@OrderBy("id ASC")
@BatchSize(size = 10)
List<Event> events = new LinkedList<>();
现在,每当调用 EventsHolder.events.add(...)
并添加到集合中的已持久托管事件时,休眠 - 在执行自动刷新时 - 将检测 EventsHolder.Events.events
集合在 org.hibernate.event.internal.DefaultFlushEntityEventListener#hasDirtyCollections
并将发出(不确定这是否是这里的重要先决条件)对 Spring Data 的 AuditingHandler 的预更新调用,这将更新 modifiedOn。
最后,optimisticLockingVersion 会递增,hibernate 发出更新语句,基本上只更新修改后的版本。
对于包含 5000 个事件的 EventsHolder,我们看到大约 4500-5000 的 optlock-versions 并且数据库的审计日志被所说的 "non-updates" 搅动,只更新修改后的版本和乐观锁定版本。
非常感谢任何关于如何阻止这种行为的想法。
通过删除间接 - 仅包含 @OneToMany 字段并将其直接内联到实体中的可嵌入 Events
- 脏检查不再持续检测集合是否脏,一切都很好现在。