9

私の列挙型はintとしてmongodbに保存されます(C#アプリから)。Javaでは、それらを取得しようとすると、例外がスローされます(enumは文字列値からのみ変換できるようです)。私にできる方法はありますか?

また、いくつかのコレクションを(Javaから)mongodbに保存すると、列挙値が文字列に変換されます(値/カーディナルではありません)。利用可能なオーバーライドはありますか?

これは、クラスレベルでmongodb-converterを作成することで実現できますが、これらの列挙型は多くの異なるクラスにあるため、クラスごとにmondodb-converterを作成したくありません。

では、フィールドレベルで何かありますか?

4

2 に答える 2

9

spring-mongodbコンバーターコードを長い間掘り下げた後、OK私は終了し、現在は機能しています:)ここにあります(より簡単な解決策があれば、私も喜んで見るでしょう、これは私がやったことです):

最初に定義する:

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つのコンバーターが必要になります。1つは単純で、もう1つはより複雑です。単純なもの(この単純な赤ちゃんは単純な変換も処理し、キャストが不可能な場合は文字列を返します。これは、列挙型を文字列として格納し、列挙型を整数として格納する場合に最適です):

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;   
            }
        }
}

そして今、ハックの部分については、私は個人的にmongoConverter内にコンバーターファクトリを登録する「programmitacly」方法を見つけられなかったので、コードを掘り下げて少しキャストしました、ここにあります(この2つの赤ちゃん関数を@Configurationに入れてくださいクラス)

      @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;
    } 
于 2015-05-04T07:19:54.123 に答える
1

カスタムコンバーターを実装し、それをスプリングに登録する必要があります。

http://static.springsource.org/spring-data/data-mongo/docs/current/reference/html/#mongo.custom-converters

于 2012-09-12T10:56:19.700 に答える