Javers 3.9.4问题:未变更的列表对象仍被标记为变更
解决Javers 3.9.4列表对象误报变更的问题
我来帮你搞定这个Javers比较时的列表变更误报问题~结合你的对象结构,大概率是以下几个原因导致的,咱们一步步来排查解决:
1. 核心原因:ServiceS1Devices未正确实现equals()和hashCode()
Javers比较集合元素时,默认会依赖对象的equals()方法判断元素是否相等。如果你的ServiceS1Devices类用的是Object类默认的equals()(只比较内存地址),那即使两个实例的字段完全相同,只要是不同的对象实例,Javers就会判定为列表元素有变更。
解决办法:为ServiceS1Devices实现业务相关的相等判断
你可以手动实现equals()和hashCode(),或者用Lombok的@EqualsAndHashCode注解来简化:
// 用Lombok的方式,基于id、name、date字段生成equals和hashCode import lombok.EqualsAndHashCode; @EqualsAndHashCode class ServiceS1Devices { String id; String name; Date date; }
如果手动实现的话,示例如下:
class ServiceS1Devices { String id; String name; Date date; @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; ServiceS1Devices that = (ServiceS1Devices) o; return Objects.equals(id, that.id) && Objects.equals(name, that.name) && Objects.equals(date, that.date); } @Override public int hashCode() { return Objects.hash(id, name, date); } }
2. 可选优化:将ServiceS1Devices标记为Javers值对象
如果ServiceS1Devices是值对象(没有唯一主键,完全由字段值定义的对象),可以给它加上Javers的@ValueObject注解,这样Javers会直接比较对象的所有字段,而不需要依赖equals()方法:
import org.javers.core.metamodel.annotation.ValueObject; @ValueObject class ServiceS1Devices { String id; String name; Date date; }
或者在Javers初始化时配置:
Javers javers = JaversBuilder.javers() .registerValueObject(ServiceS1Devices.class) .build();
3. 验证列表元素的实例一致性
确保你创建两个MyClass实例时,列表中的ServiceS1Devices元素要么是同一个实例,要么是equals()返回true的实例。比如不要在两个实例中分别new出字段完全相同但内存地址不同的ServiceS1Devices对象(除非已经实现了正确的equals())。
内容的提问来源于stack exchange,提问作者user9176614
相关产品推荐
相关产品推荐

