Mi las enumeraciones son almacenados como int en mongodb (desde C# app). Ahora en Java, cuando intento recuperar, se lanza una excepción (parece enum puede ser convertida de la cadena de valor único). Es allí cualquier manera lo puedo hacer?

También cuando me guarde algunas colecciones en mongodb (de Java), que convierte los valores de enumeración para cadena (no su valor/cardenal). Hay alguna posibilidad de anulación?

Esto puede lograrse mediante la escritura de mongodb-convertidor de nivel de clase, pero no quiero escribir mondodb convertidor para cada clase como estas enumeraciones son de muchas clases diferentes.

Así que tenemos algo en el nivel de campo?

InformationsquelleAutor gsagrawal | 2012-09-12

2 Comentarios

  1. 9

    Después de un largo excavación en la primavera-mongodb convertidor de código,
    Ok he terminado y ahora funciona 🙂 aquí está (si no es la solución más sencilla, voy a ser feliz de ver tan bien, esto es lo que yo he hecho ) :

    definir primero :

    public interface IntEnumConvertable {
          public int getValue();    

    }

    y una simple enumeración que lo implementa :

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

    Ok, ahora usted ahora tendrá 2 convertidores , es simple ,
    el otro es más complejo. el simple (presente simple bebé es también el manejo de la simple convertir y devuelve una cadena cuando la conversión no es posible, que es grande si usted quiere tener enum almacenan como cadenas y para la enumeración que son números que se almacenan como números enteros) :

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

    el más complejo , en realidad es un convertidor de fábrica :

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

    y ahora para el hack parte , me personnaly no encontrar ninguna «programmitacly» modo de registrar un convertidor de fábrica dentro de una mongoConverter , así que cavaron en el código y con un poco de casting , aquí es (poner este 2 bebés funciones en su @clase de Configuración)

          @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;
        } 
    • Gracias. He utilizado una idea para implementar LowerStringToEnumConverter
    • Muchas gracias! Es muy cable de la primavera de datos no proporcionan la manera simple de hacer que
    • Esto fue muy útil.
  2. 2

    Necesitará para implementar su convertidores personalizados y registrarlo con la primavera.

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

    • que va a trabajar en el nivel de clase .. no quiero que **ya se ha mencionado esto en la pregunta
    • No se dio cuenta (formato de tu pregunta por favor, difícil de leer) – ¿usted lo intente. Creo que funciona para los campos así.
    • La otra opción es añadir otro getter / setter para enteros a su entidad que realiza la conversión. La función de captador/definidor de la enumeración debe ser marcada como @Transitoria.
    • toma la primera entrada de la clase . por lo que no será genérico ,para cada enum/clase tengo que añadir un convertidor. Otra opción que u dio funciona bien, pero este es el tipo de solución .
    • Esto fue útil.

Dejar respuesta

Please enter your comment!
Please enter your name here