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

防止Hibernate对具有脏OneToMany集合的实体发出不必要的更新,hibernate,spring-data-jpa,optimistic-locking,auditing,dirty-checking,Hibernate,Spring Data Jpa,Optimistic Locking,Auditing,Dirty Checking,我们将Hibernate 5.3.13与Spring数据JPA 2.1.12一起使用,并且当有一个已持久化的、受管理的最小实体时,如下所示: @Entity @Table(name = "EventsHolder") @Access(AccessType.FIELD) class EventsHolder { @LastModifiedDate @Column(name = "modifiedon", nullable = false) @Temporal(TIMESTA

我们将Hibernate 5.3.13与Spring数据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
@Access(AccessType.FIELD)
class Events {

    @OneToMany(mappedBy = ...)
    @OrderBy("id ASC")
    @BatchSize(size = 10)
    List<Event> events = new LinkedList<>();
@可嵌入
@访问权限(AccessType.FIELD)
班级活动{
@OneToMany(mappedBy=…)
@订购人(“id ASC”)
@批量大小(大小=10)
列表事件=新建LinkedList();
现在,无论何时调用
EventsHolder.events.add(…)
在集合中添加了一个已持久化的托管事件后,hibernate在执行自动刷新时,将在
org.hibernate.event.internal.DefaultFlushentyEventListener#hasDirtyCollections中检测到
EventsHolder.Events.Events
集合为脏集合
并将向Spring Data的AuditingHandler发出(不确定这是否是重要的先决条件)更新前调用,该调用将更新modifiedOn

最后,optimisticLockingVersion将增加,hibernate将发出一条update语句,该语句基本上只更新已修改的版本

对于包含5000个事件的EventsHolder,我们可以看到大约4500-5000个optlock版本,并且数据库的审计日志会被称为“非更新”,只会在上面修改更新和乐观锁定版本


任何关于如何停止这种行为的想法都非常受欢迎。

通过删除间接(只包含@OneToMany字段的可嵌入
事件)并将其直接内联到实体中,脏检查不再持续检测到集合为脏,现在一切都好了