Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Spring-Mongodb将枚举存储/检索为int而不是string_Spring_Mongodb_Spring Mongo - Fatal编程技术网

Spring-Mongodb将枚举存储/检索为int而不是string

Spring-Mongodb将枚举存储/检索为int而不是string,spring,mongodb,spring-mongo,Spring,Mongodb,Spring Mongo,我的枚举在mongodb中存储为int(来自C#app)。现在在Java中,当我试图检索它们时,它抛出一个异常(似乎枚举只能从字符串值转换)。我有什么办法可以做吗 另外,当我将一些集合保存到mongodb(来自Java)时,它会将枚举值转换为字符串(而不是它们的值/基数)。是否有可用的覆盖 这可以通过在类级别编写mongodb转换器来实现,但我不想为每个类编写mondodb转换器,因为这些枚举位于许多不同的类中 那么,我们在字段级别上有什么吗?您需要实现自定义转换器,并向spring注册它 在长

我的枚举在mongodb中存储为int(来自C#app)。现在在Java中,当我试图检索它们时,它抛出一个异常(似乎枚举只能从字符串值转换)。我有什么办法可以做吗

另外,当我将一些集合保存到mongodb(来自Java)时,它会将枚举值转换为字符串(而不是它们的值/基数)。是否有可用的覆盖

这可以通过在类级别编写mongodb转换器来实现,但我不想为每个类编写mondodb转换器,因为这些枚举位于许多不同的类中


那么,我们在字段级别上有什么吗?

您需要实现自定义转换器,并向spring注册它


在长时间挖掘spring mongodb转换器代码后, 好的,我完成了,现在它工作了:)在这里(如果有更简单的解决方案,我也很乐意看到,这就是我所做的):

首先定义:

public interface IntEnumConvertable {
      public int getValue();    
}
以及实现它的简单枚举:

public enum tester implements IntEnumConvertable{   
    vali(0),secondvali(1),thirdvali(5);

    private final int val;
    private tester(int num)
    {
        val = num;          
    }
    public int getValue(){
        return val;
    }
}
好的,现在你需要2个转换器,一个很简单, 另一个更复杂。简单的一个(这个简单的婴儿也在处理简单的转换,当无法进行强制转换时返回一个字符串,如果您希望将enum存储为字符串,并且对于将数字存储为整数的enum,这非常好):

公共类整数转换器{
@写转换器
公共静态类EnumToIntegerConverter实现Converter enumType=targetType;
while(enumType!=null&&!enumType.isEnum()){
enumType=enumType.getSuperclass();
}
if(enumType==null){
抛出新的IllegalArgumentException(
“目标类型”+targetType.getName()+“未引用枚举”);
}
返回新的IntegerToEnum(枚举类型);
}
@读取转换器
公共静态类IntegerToEnum实现转换器{
私有最终类枚举类型;
公共IntegerToEnum(类enumType){
this.enumType=enumType;
}
@凌驾
公共枚举转换(整数源){
对于(T:enumType.getEnumConstants()){
if(可转换意向的t实例)
{
if(((IntEnumConvertable)t).getValue()==source.intValue()){
返回t;
}                         
}                     
}
返回null;
}
}
}
现在对于hack部分,我个人没有找到任何“programmitacly”方法在mongoConverter中注册转换器工厂,所以我在代码中进行了挖掘,并进行了一些转换,就是这样(将这两个婴儿函数放在@Configuration类中)

@Bean
公共CustomConversions CustomConversions(){
列表>();
添加(新的IntegerEnumConverters.EnumToIntegerConverter());
//这是一个虚拟注册,实际上是一个解决方案,因为
//spring mongodb没有注册转换器工厂的选项。
//所以我们注册了我们工厂使用的转换器。
add(新的IntegerToEnumConverterFactory.IntegerToEnum(null));
返回新的自定义转换(转换器);
}
@豆子
公共映射MongoConverter MappingMongoConverter()引发异常{
MongoMappingContext mappingContext=新建MongoMappingContext();
mappingContext.setApplicationContext(appContext);
DbRefResolver DbRefResolver=新的默认DbRefResolver(mongoDbFactory());
MappingMongoConverter mongoConverter=新的MappingMongoConverter(dbRefResolver,mappingContext);
setCustomConversions(customConversions());
ConversionService convService=mongoConverter.getConversionService();
((GenericConversionService)convService).addConverterFactory(新的IntegerToEnumConverterFactory());
mongoConverter.AfterPropertieSet();
返回mongoConverter;
} 

这将在课堂上起作用。。我不希望**在问题中已经提到了这一点,但没有注意到(请格式化你的问题,很难阅读)-你试过了吗。我认为它也适用于字段。另一个选项是向进行转换的实体中添加另一个int的getter/setter。枚举的getter/setter应标记为@Transient。它将第一个输入作为类。所以它不是泛型的,对于每个枚举/类,我必须添加一个转换器。u给出的另一个选项很好,但这是一种解决方法。上面的回执对我来说并不顺利,因为Spring Mongo开始应用给定的转换器将
Integer
类型的所有查询值转换为
Enum
,在我的例子中,这样就导致了所有整型值的
null
s。为了解决这个问题,我必须将
@ReadingConverter
放在转换器工厂(因此将其从
IntegerToEnum
转换器中删除)。
public class IntegerEnumConverters {
    @WritingConverter
    public static class EnumToIntegerConverter implements Converter<Enum<?>, Object> {
        @Override
        public Object convert(Enum<?> source) {
            if(source instanceof IntEnumConvertable)
            {
                return ((IntEnumConvertable)(source)).getValue();
            }
            else
            {
                return source.name();
            }               
        }
    }   
 }
public class IntegerToEnumConverterFactory implements ConverterFactory<Integer, Enum> {
        @Override
        public <T extends Enum> Converter<Integer, T> getConverter(Class<T> targetType) {
            Class<?> enumType = targetType;
            while (enumType != null && !enumType.isEnum()) {
                enumType = enumType.getSuperclass();
            }
            if (enumType == null) {
                throw new IllegalArgumentException(
                        "The target type " + targetType.getName() + " does not refer to an enum");
            }
            return new IntegerToEnum(enumType);
        }
        @ReadingConverter
        public static class IntegerToEnum<T extends Enum>  implements Converter<Integer, Enum> {
            private final Class<T> enumType;

            public IntegerToEnum(Class<T> enumType) {
                this.enumType = enumType;
            }

            @Override
            public Enum convert(Integer source) {
                  for(T t : enumType.getEnumConstants()) {
                      if(t instanceof IntEnumConvertable)
                      {
                          if(((IntEnumConvertable)t).getValue() == source.intValue()) {
                                return t;
                            }                         
                      }                     
                    }
                    return null;   
            }
        }
}
      @Bean
        public CustomConversions customConversions() {
            List<Converter<?, ?>> converters = new ArrayList<Converter<?, ?>>();
            converters.add(new IntegerEnumConverters.EnumToIntegerConverter());     
// this is a dummy registration , actually it's a work-around because
// spring-mongodb doesnt has the option to reg converter factory.
// so we reg the converter that our factory uses. 
converters.add(new IntegerToEnumConverterFactory.IntegerToEnum(null));      
            return new CustomConversions(converters);
        }

    @Bean
    public MappingMongoConverter mappingMongoConverter() throws Exception {
        MongoMappingContext mappingContext = new MongoMappingContext();
        mappingContext.setApplicationContext(appContext);
        DbRefResolver dbRefResolver = new DefaultDbRefResolver(mongoDbFactory());
        MappingMongoConverter mongoConverter = new MappingMongoConverter(dbRefResolver, mappingContext);        
        mongoConverter.setCustomConversions(customConversions());       
        ConversionService convService = mongoConverter.getConversionService();
        ((GenericConversionService)convService).addConverterFactory(new IntegerToEnumConverterFactory());                  
        mongoConverter.afterPropertiesSet();
        return mongoConverter;
    }