为什么 Spring-content 在启动时产生 IllegalStateException 如果实体有一个标有 @Enumerated 的字段

Why does Spring-content produce an IllegalStateException on startup if an Entity has a field which is marked with @Enumerated

我们正在使用 Spring-content 作为网络应用程序中的文件存储解决方案,并将版本从 1.0.0.M10 升级到 2.1.0。突然我们的微服务拒绝启动,因为它无法加载它的 ApplicationContext,我无法理解为什么。 Spring-content changelog 提到了涉及装饰 ContentStore 本身的注释的重大更改——我们没有——但我读到的没有提到实体 class 上的注释。我做错了什么,或者这是某种错误?

我做了一个简化的示例,它会产生相同类型的异常,因为我不确定是否允许我共享原始源代码。

我的 Spring-内容依赖项。唯一的其他依赖项是在一个新项目上的 lombok、postgres 和 hibernate:

        <dependency>
            <groupId>com.github.paulcwarren</groupId>
            <artifactId>spring-content-fs-boot-starter</artifactId>
            <version>2.1.0</version>
        </dependency>
        <dependency>
            <groupId>com.github.paulcwarren</groupId>
            <artifactId>spring-content-rest-boot-starter</artifactId>
            <version>2.1.0</version>
        </dependency>

我的实体:

@Data
@Table(name = "employee")
public class EmployeeEntity  {

    @Id
    @Column(name = "id")
    private UUID employeeId;
    
    @ContentId
    @Column(name = "content_id")
    private UUID contentId;
    
    @Enumerated(EnumType.STRING)
    @Column(name = "employee_type")
    private EmployeeType employeeType;

}

枚举:

public enum EmployeeType {
    ASSOCIATE,
    MANAGER,
    DIRECTOR,
    EXECUTIVE;
}

我的回购:

public interface IEmployeeRepository extends JpaRepository<EmployeeEntity, UUID> {

}

还有我的 ContentStore:

public interface IEmployeeContentStore extends ContentStore<EmployeeEntity, String> {

}

当我尝试 运行 应用程序或 运行 加载上下文的 JUnit 测试时,我得到一个充满这些错误的控制台,它似乎早在我可以滚动。

    at org.springframework.content.commons.mappingcontext.ContentPropertyBuilderVisitor.visitField(ContentPropertyBuilderVisitor.java:143) ~[spring-content-commons-2.1.0.jar:na]
    at org.springframework.content.commons.mappingcontext.ClassWalker.accept(ClassWalker.java:24) ~[spring-content-commons-2.1.0.jar:na]

通过将控制台输出捕获到文本文件,这似乎是根异常:

Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.content.commons.mappingcontext.MappingContext]: Factory method 'mappingContext' threw exception; nested exception is java.lang.WhosebugError
    at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:185) ~[spring-beans-5.3.18.jar:5.3.18]
    at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:653) ~[spring-beans-5.3.18.jar:5.3.18]
    ... 134 common frames omitted
Caused by: java.lang.WhosebugError: null
    at java.base/java.lang.reflect.Field.copy(Field.java:153) ~[na:na]
    at java.base/java.lang.reflect.ReflectAccess.copyField(ReflectAccess.java:151) ~[na:na]
    at java.base/jdk.internal.reflect.ReflectionFactory.copyField(ReflectionFactory.java:381) ~[na:na]
    at java.base/java.lang.Class.copyFields(Class.java:3383) ~[na:na]
    at java.base/java.lang.Class.getDeclaredFields(Class.java:2249) ~[na:na]
    at org.springframework.content.commons.mappingcontext.ContentPropertyBuilderVisitor.visitClass(ContentPropertyBuilderVisitor.java:48) ~[spring-content-commons-2.1.0.jar:na]
    at org.springframework.content.commons.mappingcontext.ClassWalker.accept(ClassWalker.java:17) ~[spring-content-commons-2.1.0.jar:na]

我已将问题追溯到似乎是实体 class 上的 @Enumerated 注释。删除此字段可完全防止异常发生。

我能找到的最接近的解释是,如果 classes 递归地互相调用,那么 WhosebugException 是您所期望的: 然而,这至少不能直接适用,因为我示例中的实体之间没有任何映射。

我尝试过的事情:

似乎唯一可行的解​​决方案是将 EmployeeType 更改为字符串,在这种情况下,一切都会正确加载。如果这是唯一的解决方案,那就不太理想了,因为必须重构整个微服务,以便为该字段使用字符串而不是枚举。

任何人都可以指出正确的方向,使枚举字段以这种方式在 ContentStore 中使用的实体中工作吗?非常感谢!


编辑:添加了我最初忽略的 postgres 和 hibernate 依赖项

Arnaud 的 link 指出了正确的解决方案。当 spring-content 依赖项更新为 2.2.0-SNAPSHOT:

时,该服务现在将按预期启动
        <dependency>
            <groupId>com.github.paulcwarren</groupId>
            <artifactId>spring-content-fs-boot-starter</artifactId>
            <version>2.2.0-SNAPSHOT</version>
        </dependency>

再次感谢!