2012-09-12 11 views
5

मेरे enums mongodb (सी # ऐप से) में int के रूप में संग्रहीत हैं। अब जावा में, जब मैं उन्हें पुनर्प्राप्त करने का प्रयास करता हूं, तो यह एक अपवाद फेंकता है (ऐसा लगता है कि enum केवल स्ट्रिंग मान से परिवर्तित किया जा सकता है)। क्या मैं ऐसा कर सकता हूं?स्प्रिंग-मोंगोडब स्ट्रिंग/intrieइंग enums स्ट्रिंग

साथ ही जब मैं कुछ संग्रहों को मोंगोडब (जावा से) में सहेजता हूं, तो यह enum मानों को स्ट्रिंग में परिवर्तित करता है (उनके मूल्य/कार्डिनल नहीं)। क्या कोई ओवरराइड उपलब्ध है?

यह कक्षा स्तर पर मोंगोड-कनवर्टर लिखकर हासिल किया जा सकता है लेकिन मैं प्रत्येक वर्ग के लिए मॉन्डोड-कनवर्टर लिखना नहीं चाहता क्योंकि ये enums कई अलग-अलग वर्गों में हैं।

तो क्या हमारे पास क्षेत्र स्तर पर कुछ है?

उत्तर

8

वसंत-MongoDB कनवर्टर कोड में एक लंबा खुदाई के बाद, ठीक है मैं समाप्त हो गया और अब यह काम कर रहा है :) यहाँ यह है (यदि वहाँ सरल समाधान है मैं भी देख खुश हो जाएगा, यह है मैं क्या किया है):

पहले निर्धारित करें:

public interface IntEnumConvertable { 
     public int getValue();  

}

और एक सरल enum कि औजार यह:

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

और अब हैक भाग के लिए, मैं फ्लॉप किसी भी "programmitacly" जिस तरह से एक mongoConverter भीतर एक कनवर्टर कारखाना रजिस्टर करने के लिए लगता है personnaly, तो मैं:

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

अधिक जटिल एक है, वास्तव में एक कनवर्टर कारखाना है कोड में खोला गया और थोड़ा कास्टिंग के साथ, यहां यह है (इस 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; 
    } 
+1

धन्यवाद। मैंने LowerStringToEnumConverter – Demwis

+1

को लागू करने के लिए एक विचार का उपयोग किया बहुत बहुत धन्यवाद! यह बहुत वायर्ड है कि वसंत डेटा – ruX

+0

करने के लिए आसान तरीका प्रदान नहीं करता है यह काफी उपयोगी था। –

2

आपको अपने कस्टम कन्वर्टर्स को लागू करने और वसंत के साथ पंजीकरण करने की आवश्यकता होगी।

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

+0

जो कक्षा स्तर पर काम करेगा .. मुझे नहीं चाहिए कि ** – gsagrawal

+0

प्रश्न में पहले से ही इसका उल्लेख किया गया है (नोटिस नहीं किया गया है, कृपया अपना प्रश्न प्रारूपित करें, पढ़ने के लिए मुश्किल है) - क्या आपने इसे आजमाया। मुझे लगता है कि यह खेतों के लिए भी काम करता है। – gkamal

+2

दूसरा विकल्प आपकी इकाई को इन्ट्स के लिए एक और गेटर/सेटर जोड़ना है जो रूपांतरण करता है। Enum के लिए गेटर/सेटर @Transient के रूप में चिह्नित किया जाना चाहिए। – gkamal