복붙노트

[SPRING] 봄 - intum 문자열로 열거 형을 저장 / 검색하는 몽고

SPRING

봄 - intum 문자열로 열거 형을 저장 / 검색하는 몽고

내 열거 형은 mongodb (C # app)의 int 형식으로 저장됩니다. 이제 Java에서 그들을 검색하려고 할 때 그것은 예외를 던졌습니다 (열거 형은 문자열 값에서만 변환 될 수있는 것 같습니다). 내가 할 수있는 방법이 있니?

또한 mongodb (Java에서)에 일부 콜렉션을 저장할 때 열거 형 값을 문자열로 변환합니다 (값 / 추기선이 아님). 사용할 수있는 오버라이드가 있습니까?

클래스 수준에서 mongodb-converter를 작성하면이 작업을 수행 할 수 있지만이 클래스는 여러 클래스에 있으므로 각 클래스에 mondodb-converter를 쓰고 싶지는 않습니다.

우리는 현장 수준에서 뭔가를 가지고 있습니까?

해결법

  1. ==============================

    1.스프링 몽고 변환기 코드를 오랫동안 파고 들자, 좋아, 내가 끝내고 지금은 작동 :) :) 여기에 (만약 내가 행복하게 볼 수있는 간단한 해결책이있다, 이것은 내가 한 일이다) :

    스프링 몽고 변환기 코드를 오랫동안 파고 들자, 좋아, 내가 끝내고 지금은 작동 :) :) 여기에 (만약 내가 행복하게 볼 수있는 간단한 해결책이있다, 이것은 내가 한 일이다) :

    먼저 정의 :

    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을 원할 경우 좋습니다).

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

    그리고 해킹 부분을 위해, 나는 personnaly didnt가 mongoConverter 내에서 변환기 팩토리를 등록하는 "programmitacly"방법을 찾지 않았다. 그래서 나는 코드에서 파고 들어왔다. 그리고 작은 캐스팅과 함께, 여기에 @Configuration에이 2 개의 아기 함수를 넣는다. 수업)

          @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;
        } 
    
  2. ==============================

    2.사용자 지정 변환기를 구현하여 봄에 등록해야합니다.

    사용자 지정 변환기를 구현하여 봄에 등록해야합니다.

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

  3. from https://stackoverflow.com/questions/12385920/spring-mongodb-storing-retrieving-enums-as-int-not-string by cc-by-sa and MIT license