SpringBoot中Javers获取ListChange仅返回ID,如何获取实际对象值?
在SpringBoot中用Javers获取一对多关联实体的完整变更版本
当你修改ParentEntity关联的ChildEntity后,Javers默认只存储关联实体的全局ID(GlobalId)而非完整对象,导致查询List<Change>时看不到具体变更内容。以下是几种解决方法:
1. 启用深度差异查询
在构建查询时添加.withDeepDiff(),让Javers递归解析关联实体的变更细节:
List<Change> changes = javers.findChanges( QueryBuilder.byInstanceId(parentId, ParentEntity.class) .withSnapshotTypeUpdate() .withDeepDiff() // 关键:开启深度分析关联实体 .build() );
此时返回的Change对象会包含ChildEntity的具体字段变更,而非仅全局ID。
2. 配置Javers级联保存关联实体快照
通过Javers配置启用级联保存,确保修改ParentEntity时,关联的ChildEntity快照也被保存:
Javers javers = JaversBuilder.javers() .registerEntity(ParentEntity.class) .registerEntity(ChildEntity.class) .withCascadeSave(true) // 级联保存关联实体快照 .build();
这种方式会让Javers在存储ParentEntity快照的同时,同步保存关联ChildEntity的快照,后续查询时能直接获取完整对象版本。
3. 手动通过GlobalId加载关联实体快照
如果需要更精细的控制,可以从Change中提取ChildEntity的GlobalId,单独查询其历史快照:
List<Change> changes = javers.findChanges( QueryBuilder.byInstanceId(parentId, ParentEntity.class) .withSnapshotTypeUpdate() .build() ); for (Change change : changes) { if (change instanceof ReferenceChange) { ReferenceChange refChange = (ReferenceChange) change; // 获取变更前后的ChildEntity全局ID GlobalId oldChildId = refChange.getLeftValue(); GlobalId newChildId = refChange.getRightValue(); // 查询旧版本快照 Snapshot oldChildSnapshot = javers.findSnapshot(oldChildId); ChildEntity oldChild = oldChildSnapshot.getState(ChildEntity.class); // 查询新版本快照 Snapshot newChildSnapshot = javers.findSnapshot(newChildId); ChildEntity newChild = newChildSnapshot.getState(ChildEntity.class); } }
注意事项
- 深度查询和级联保存会增加存储和查询开销,适合小型关联实体;大型实体建议用手动加载方式。
- 确保
ChildEntity已被Javers识别为实体(通过@Entity注解或JaversBuilder手动注册)。 - 若
ChildEntity是无ID的值对象,直接添加@ValueObject注解,Javers会自动存储完整内容。
内容的提问来源于stack exchange,提问作者Anupam Mangale
相关产品推荐
相关产品推荐

