- 异常堆栈java.lang.IllegalStateException: Expected lazy evaluation to yield a non-null value but got null!
at org.springframework.data.util.Lazy.get(Lazy.java:66)
at org.springframework.data.mapping.model.AnnotationBasedPersistentProperty.isWritable(AnnotationBasedPersistentProperty.java:211)
at org.springframework.data.mongodb.core.convert.MappingMongoConverter.writeProperties(MappingMongoConverter.java:490)
at org.springframework.data.mongodb.core.convert.MappingMongoConverter.writeInternal(MappingMongoConverter.java:481)
at org.springframework.data.mongodb.core.convert.MappingMongoConverter.writeInternal(MappingMongoConverter.java:455)
at org.springframework.data.mongodb.core.convert.MappingMongoConverter.write(MappingMongoConverter.java:399)
at org.springframework.data.mongodb.core.convert.MappingMongoConverter.write(MappingMongoConverter.java:78)
at org.springframework.data.mongodb.core.MongoTemplate.toDocument(MongoTemplate.java:1071)
at org.springframework.data.mongodb.core.MongoTemplate.doInsertBatch(MongoTemplate.java:1164)
at org.springframework.data.mongodb.core.MongoTemplate.insert(MongoTemplate.java:1116) - 问题定位:
org.springframework.data.mapping.model.AnnotationBasedPersistentProperty#isWritable这个对象内部维护了一个lambda表达式,是懒加载方式获取的。
private final Lazy<Boolean> isWritable = Lazy .of(() -> !isTransient() && !isAnnotationPresent(ReadOnlyProperty.class));
public T get() { T value = getNullable(); if (value == null) { throw new IllegalStateException("Expected lazy evaluation to yield a non-null value but got null!"); } return value; }
@Nullable private T getNullable() { T value = this.value; if (this.resolved) { return value; } value = supplier.get(); this.value = value; this.resolved = true; return value; }
Lazy内部的getNullable里面会设置解析标记,单线程情况下面,一切都是正常的,多线程情况下面,怀疑是resolved这个标记被刷回内存回内存导致的,而value还是在线程本地缓存中,原因有可能是jvm重排序,导致以上的顺序问题。
以上是本渣渣的猜测,因为是生产环境的,本地jvm无法验证,而且出现概率很低,只有在启动的时候出现过一次。希望有大神帮助解答。
shfq 已回答的问题