代码之家  ›  专栏  ›  技术社区  ›  Kevin Amiranoff

Spring MongoDB:没有枚举常量错误

  •  0
  • Kevin Amiranoff  · 技术社区  · 7 年前

    Java初学者,

    我正试图定义我的模型,以便使用spring从我的mongodb数据库访问数据。

    我想将gender定义为枚举,其中在数据库中,值存储为字符串: male female

    但我得到了以下错误: No enum constant com.nemeantalestudios.mythology.models.Gender.male

    这是我的身材波乔:

    @Getter
    @Setter
    @Document(collection = "figures")
    public class Figure {
    
        @Id
        public String id;
        public String name;
        public String greekName;
        public String romanName;
        public String description;
        public String category;
        public String immortal;
        public Gender gender;
    }
    

    以下是我的性别统计表:

    public enum Gender {
        MALE("male"),
        FEMALE("female");
    
        private final String text;
    
        Gender(final String text) {
            this.text = text;
        }
    
        @Override
        public String toString() {
            return text;
        }
    }
    

    这就是我试图访问它的方式:

    @重写 公共void运行(字符串…args)引发异常{ 可选chronos=figurepository.findbyid(“5893a17a88dcfdf6dfa73429”); list figureset=数字存储.findall(); system.out.println(图set.size());

    chronos.ifPresent(figure -> {
        System.out.println(figure.name);
        System.out.println(figure.category);
        System.out.println(figure.description);
        System.out.println(figure.immortal);
        System.out.println(figure.romanName);
        System.out.println(figure.greekName);
        System.out.println(figure.gender.toString());
    });
    

    }

    如果这里是stacktrace:

    Caused by: java.lang.IllegalArgumentException: No enum constant com.nemeantalestudios.mythology.models.Gender.male
        at java.lang.Enum.valueOf(Enum.java:238) ~[na:1.8.0_171]
        at org.springframework.data.mongodb.core.convert.MappingMongoConverter.getPotentiallyConvertedSimpleRead(MappingMongoConverter.java:884) ~[spring-data-mongodb-2.0.8.RELEASE.jar:2.0.8.RELEASE]
        at org.springframework.data.mongodb.core.convert.MappingMongoConverter.readValue(MappingMongoConverter.java:1392) ~[spring-data-mongodb-2.0.8.RELEASE.jar:2.0.8.RELEASE]
        at org.springframework.data.mongodb.core.convert.MappingMongoConverter$MongoDbPropertyValueProvider.getPropertyValue(MappingMongoConverter.java:1335) ~[spring-data-mongodb-2.0.8.RELEASE.jar:2.0.8.RELEASE]
        at org.springframework.data.mongodb.core.convert.MappingMongoConverter.readProperties(MappingMongoConverter.java:335) ~[spring-data-mongodb-2.0.8.RELEASE.jar:2.0.8.RELEASE]
        at org.springframework.data.mongodb.core.convert.MappingMongoConverter.read(MappingMongoConverter.java:297) ~[spring-data-mongodb-2.0.8.RELEASE.jar:2.0.8.RELEASE]
        at org.springframework.data.mongodb.core.convert.MappingMongoConverter.read(MappingMongoConverter.java:253) ~[spring-data-mongodb-2.0.8.RELEASE.jar:2.0.8.RELEASE]
        at org.springframework.data.mongodb.core.convert.MappingMongoConverter.read(MappingMongoConverter.java:202) ~[spring-data-mongodb-2.0.8.RELEASE.jar:2.0.8.RELEASE]
        at org.springframework.data.mongodb.core.convert.MappingMongoConverter.read(MappingMongoConverter.java:198) ~[spring-data-mongodb-2.0.8.RELEASE.jar:2.0.8.RELEASE]
        at org.springframework.data.mongodb.core.convert.MappingMongoConverter.read(MappingMongoConverter.java:86) ~[spring-data-mongodb-2.0.8.RELEASE.jar:2.0.8.RELEASE]
        at org.springframework.data.mongodb.core.MongoTemplate$ReadDocumentCallback.doWith(MongoTemplate.java:2785) ~[spring-data-mongodb-2.0.8.RELEASE.jar:2.0.8.RELEASE]
        at org.springframework.data.mongodb.core.MongoTemplate.executeFindOneInternal(MongoTemplate.java:2401) ~[spring-data-mongodb-2.0.8.RELEASE.jar:2.0.8.RELEASE]
        at org.springframework.data.mongodb.core.MongoTemplate.doFindOne(MongoTemplate.java:2193) ~[spring-data-mongodb-2.0.8.RELEASE.jar:2.0.8.RELEASE]
        at org.springframework.data.mongodb.core.MongoTemplate.findById(MongoTemplate.java:797) ~[spring-data-mongodb-2.0.8.RELEASE.jar:2.0.8.RELEASE]
        at org.springframework.data.mongodb.repository.support.SimpleMongoRepository.findById(SimpleMongoRepository.java:121) ~[spring-data-mongodb-2.0.8.RELEASE.jar:2.0.8.RELEASE]
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_171]
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_171]
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_171]
        at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_171]
        at org.springframework.data.repository.core.support.RepositoryComposition$RepositoryFragments.invoke(RepositoryComposition.java:377) ~[spring-data-commons-2.0.8.RELEASE.jar:2.0.8.RELEASE]
        at org.springframework.data.repository.core.support.RepositoryComposition.invoke(RepositoryComposition.java:200) ~[spring-data-commons-2.0.8.RELEASE.jar:2.0.8.RELEASE]
        at org.springframework.data.repository.core.support.RepositoryFactorySupport$ImplementationMethodExecutionInterceptor.invoke(RepositoryFactorySupport.java:629) ~[spring-data-commons-2.0.8.RELEASE.jar:2.0.8.RELEASE]
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185) ~[spring-aop-5.0.7.RELEASE.jar:5.0.7.RELEASE]
        at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.doInvoke(RepositoryFactorySupport.java:593) ~[spring-data-commons-2.0.8.RELEASE.jar:2.0.8.RELEASE]
        at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.invoke(RepositoryFactorySupport.java:578) ~[spring-data-commons-2.0.8.RELEASE.jar:2.0.8.RELEASE]
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185) ~[spring-aop-5.0.7.RELEASE.jar:5.0.7.RELEASE]
        at org.springframework.data.projection.DefaultMethodInvokingMethodInterceptor.invoke(DefaultMethodInvokingMethodInterceptor.java:59) ~[spring-data-commons-2.0.8.RELEASE.jar:2.0.8.RELEASE]
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185) ~[spring-aop-5.0.7.RELEASE.jar:5.0.7.RELEASE]
        at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92) ~[spring-aop-5.0.7.RELEASE.jar:5.0.7.RELEASE]
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185) ~[spring-aop-5.0.7.RELEASE.jar:5.0.7.RELEASE]
        at org.springframework.data.repository.core.support.SurroundingTransactionDetectorMethodInterceptor.invoke(SurroundingTransactionDetectorMethodInterceptor.java:61) ~[spring-data-commons-2.0.8.RELEASE.jar:2.0.8.RELEASE]
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185) ~[spring-aop-5.0.7.RELEASE.jar:5.0.7.RELEASE]
        at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:212) ~[spring-aop-5.0.7.RELEASE.jar:5.0.7.RELEASE]
        at com.sun.proxy.$Proxy50.findById(Unknown Source) ~[na:na]
        at com.nemeantalestudios.mythology.MythologyApplication.run(MythologyApplication.java:31) [classes/:na]
        at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:797) [spring-boot-2.0.3.RELEASE.jar:2.0.3.RELEASE]
    

    我做错什么了?

    1 回复  |  直到 7 年前
        1
  •  2
  •   Andrei Sfat systemfreund    7 年前

    您需要为spring数据创建自定义转换器,以了解如何处理枚举中的字符串。

    public class FigureConverter {
    
        @ReadingConverter
        public static class GenderConverter implements Converter<String, Gender> {
    
            @Override
            public Gender convert(final String source) {
                return Gender.fromString(source);
            }
        }
    
    }
    

    以及启用转换器的配置:

    @Configuration
    public class MongoDBConfig {
    
        @Autowired
        private MongoProperties mongoProperties;
    
        @Autowired
        private MongoClient mongoClient;
    
    
        @Bean
        public MongoTemplate mongoTemplate() {
    
            MongoTemplate mongoTemplate = new MongoTemplate(mongoClient, mongoProperties.getDatabase());
            MappingMongoConverter mongoMapping = (MappingMongoConverter) mongoTemplate.getConverter();
            mongoMapping.setCustomConversions(customConversions()); // tell mongodb to use the custom converters
            mongoMapping.afterPropertiesSet();
            return mongoTemplate;
    
        }
    
    
        public MongoCustomConversions customConversions() {
            return new MongoCustomConversions(Collections.singletonList(new GenderConverter()));
        }
    }
    

    您可能还希望使用相同的转换器保存数据。你只需要添加一个 @WritingConverter 为了达到这个目的。

    我建议您使用枚举本身,而不是字符串,因为在这种情况下,您可以利用spring数据来处理转换。因此,如果您将其保存为一个普通的枚举,那么您将得到mongo中保存为“male”或“female”的枚举,spring数据将知道如何自动转换该枚举。