有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java无法读取枚举属性ClassCastException

对于我的模型,我在读取枚举属性时遇到问题。从mongoDB读取后,属性“value”的类型为String,而不是MyEnum

我的模型:

public class Record {
    @Id
    public String id;
    public Wrapper<MyEnum> wrappedEnum;
   ...
}

public class Wrapper<T extends Enum<?>> extends BaseWrapper<T>{
    ...
}

public class BaseWrapper<T> {
    public T value;
    ...
}

代码:

 Record record = new Record();
        Wrapper<MyEnum> wrapper = new Wrapper<>();
        wrapper.setValue(MyEnum.A);
        record.setWrappedEnum(wrapper);
        repository.save(record);


        repository.findAll().forEach(rec -> {
            Object value = rec.getWrappedEnum().value;
            System.out.println("rec.getWrappedEnum().value: " + value); // rec.getWrappedEnum().value: A
            System.out.println("rec.getWrappedEnum().getValue(): " + value.getClass()); // rec.getWrappedEnum().getValue(): class java.lang.String
            MyEnum valEnum = rec.getWrappedEnum().getValue(); // throws Caused by: java.lang.ClassCastException: class java.lang.String cannot be cast to class com.example.MyEnum (java.lang.String is in module java.base of loader 'bootstrap'; com.example.MyEnum is in unnamed module of loader 'app')
        });

是否有任何选项可以配置mongodb以正确读取此模型


共 (1) 个答案

  1. # 1 楼答案

    得到ClassCastException的原因是,您没有指定持久化层实际应该如何持久化包装的枚举

    我想您正在使用JPA作为持久性API。实际上有多种方法可以实现你想要的。对于您的案例来说,更方便的方法是注册一个转换器,以便JPA知道如何持久化您的枚举并将其映射回。一个基本示例可能如下所示(请注意,BaseWrapper中的值字段有setter):

    @Converter
    public class WrapperConverter implements AttributeConverter<Wrapper, String> {
    
      @Override
      public String convertToDatabaseColumn(Wrapper attribute) {
        return attribute.getValue().toString();
      }
    
      @Override
      public Wrapper convertToEntityAttribute(String dbData) {
        MyEnum myEnum = MyEnum.valueOf(dbData);
        Wrapper<MyEnum> wrappedEnum = new Wrapper<>();
        wrappedEnum.setValue(myEnum);
        return wrappedEnum;
      }
    }
    

    注册转换器:

    @Entity
    public class Record {
      @Id
      private String id;
    
      @Convert(converter = WrapperConverter.class)
      private Wrapper<MyEnum> wrappedEnum;