我们将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的Pre-Update调用,这将更新ModifyedOn。
最后,optimisticLockingVersion将递增,并且休眠发出一条更新语句,该语句基本上仅更新修改后的版本和版本。
[使用包含5000个事件的EventsHolder,我们看到optlock版本在4500-5000附近,数据库的审核日志与所说的“非更新”不符,后者仅更新修改后的版本和乐观锁定版本。
关于如何停止这种行为的任何想法都非常感谢。
通过删除间接方法-仅包含@OneToMany字段的可嵌入Events
并将其直接内联到实体中-脏检查不再继续将集合视为脏对象,并且现在一切都很好。