2014-09-19 1 views
1

Я следующий интерфейсMorphia Интерфейс Список перечислимого не работает (демаршаллизация)

@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS, include = JsonTypeInfo.As.PROPERTY, property = "className") 
public interface InfoChartInformation { 
    public String name(); 
} 

И следующий реализации (перечисления):

public class InfoChartSummary {  
    public static enum Immobilien implements InfoChartInformation { 
     CITY, CONSTRUCTION_DATE; 
    } 
    public static enum Cars implements InfoChartInformation { 
     POWER, MILEAGE; 
    } 
} 

Затем я использую все это в следующий объект:

@Entity(noClassnameStored = true) 
@Converters(InfoChartInformationMorphiaConverter.class) 
public class TestEntity{ 
    @Id 
    public ObjectId id; 
    @Embedded 
    public List<InfoChartInformation> order; 
} 

Джексон, чтобы обнаружить тип на немаршалинг время, добавит к каждому е num в списке className.

Я думал, что морфий будет делать то же самое, но там нет ни одного поля имени класса в списке перечисления и демаршаллинг не может быть сделан правильно: java.lang.RuntimeException: java.lang.RuntimeException: java.lang.RuntimeException: java.lang.ClassCastException: java.lang.String cannot be cast to com.mongodb .DBObject

Я предполагаю, что правильное поведение должно быть, чтобы сохранить весь маршрут перечислимого (package + name), а не только имя перечисления. По крайней мере, таким образом можно было бы провести разборку. Есть способ, которым морфия поддерживает это по умолчанию, или мне нужно создать свой собственный конвертер (similar to this)?

ответ

1

Я попытался создать пользовательский конвертер:

public class InfoChartInformationMorphiaConverter extends TypeConverter{ 
    public InfoChartInformationMorphiaConverter() { 
     super(InfoChartInformation.class); 
    } 
    @Override 
    public Object decode(Class targetClass, Object fromDBObject, MappedField optionalExtraInfo) { 
     if (fromDBObject == null) { 
      return null; 
     } 
     String clazz = fromDBObject.toString().substring(0, fromDBObject.toString().lastIndexOf(".")); 
     String value = fromDBObject.toString().substring(fromDBObject.toString().lastIndexOf(".") + 1); 
     try { 
      return Enum.valueOf((Class)Class.forName(clazz), value); 
     } catch (ClassNotFoundException e) { 
      return null; 
     } 
    } 
    @Override 
    public Object encode(final Object value, final MappedField optionalExtraInfo) { 
     return value.getClass().getName() + "." + ((InfoChartInformation) value).name(); 
    } 
} 

Затем я добавил информацию преобразователя к морфию morphia.getMapper().getConverters().addConverter(new InfoChartInformationMorphiaConverter());.

Однако при сериализации (или сортировочный) объекта, чтобы сохранить его в базу данных, пользовательского преобразователь игнорируется и Enum сохраняется с использованием по умолчанию Морфий преобразователя (только имя перечисления).

Если я использую в классе TestEntity только атрибут InfoChartInformation; вместо List<>InfoChartInformation>, мой клиентский конвертер будет работать. Однако мне нужна поддержка для списка