2016-08-29 2 views
2

Я работаю в Spring Boot с проектом Spring Data MongoDB, и я вижу поведение, о котором я не знаю. Я понимаю, что поле id будет находиться в _id в репозитории Mongo за http://docs.spring.io/spring-data/mongodb/docs/current/reference/html/#mapping.conventions.id-field. Моя проблема заключается в том, что это также происходит для дочерних объектов, которые не кажутся правильными.Обработка полей Id в Spring Data Mongo для дочерних объектов

Например, у меня есть эти классы (выезд из сеттеров и добытчиками для краткости):

public class MessageBuild { 
    @Id 
    private String id; 

    private String name; 
    private TopLevelMessage.MessageType messageType; 
    private TopLevelMessage message; 
} 

public interface TopLevelMessage { 
    public enum MessageType { 
     MapData 
    } 
} 

public class MapData implements TopLevelMessage { 
    private String layerType; 
    private Vector<Intersection> intersections; 
    private Vector<RoadSegment> roadSegments; 
}  

public class RoadSegment { 
    private int id; 
    private String name; 
    private Double laneWidth; 
} 

и создать объектный граф с помощью этого я использую соответствующий класс MongoRepository, чтобы сохранить я в конечном итоге с примером документа как это (с _class опущены):

{ 
    "_id" : ObjectId("57c0c05568a6c4941830a626"), 
    "_class" : "com.etranssystems.coreobjects.persistable.MessageBuild", 
    "name" : "TestMessage", 
    "messageType" : "MapData", 
    "message" : { 
     "layerType" : "IntersectionData", 
     "roadSegments" : [ 
      { 
       "_id" : 2001, 
       "name" : "Road Segment 1", 
       "laneWidth" : 3.3 
      } 
     ] 
    } 
} 

в этом случае дочерний объект с именем поля идентификатора имеет свое отображение преобразуется в _ID в хранилище MongoDB. Не конец света, хотя и не ожидаемый. Самая большая проблема заключается в том, что это показывается REST MVC, поля _id не возвращаются из запроса. Я попытался установить exposeIdsFor в моем RepositoryRestConfigurerAdapter для этого класса, и он предоставляет идентификатор для документа верхнего уровня, но не для дочерних.

Так кружась вокруг 2 вопросов/проблем я являются:

  • Почему поля объекта ребенка, отображенных в _ID? Я понимаю, что это должно произойти только на верхнем уровне, так как вещи, находящиеся под ними, на самом деле не являются документами.
  • Не должно ли конфигурация выставлять поля id для дочерних объектов в документе, если они сопоставляют имена полей?

ответ

0

Неужели я считаю, что RoadSegment не содержит getId()? От Spring's documentation:

Свойство или поле без аннотаций, но с именем идентификатор будет отображаться в поле _ID.

Я считаю, что Spring Data делает это даже для вложенных классов, когда находит поле id. Вы можете либо добавить getId(), так что поле называется id или аннотировать его с @Field:

public class RoadSegment { 
    @Field("id") 
    private int id; 

    private String name; 
    private Double laneWidth; 
} 

Я согласен, это автоматическое преобразование идентификатора/_id должно быть сделано только на самом высоком уровне, на мой взгляд.

Однако то, как Спринг данные Монго преобразование кодируется, все Java ojects пройти через точного же код, чтобы быть преобразованы в JSON (сверху и вложенные объекты):

public class MappingMongoConverter { 
... 
    protected void writeInternal(Object obj, final DBObject dbo, MongoPersistentEntity<?> entity) { 
     ... 
     if (!dbo.containsField("_id") && null != idProperty) { 
     try { 
      Object id = accessor.getProperty(idProperty); 
       dbo.put("_id", idMapper.convertId(id)); 
      } catch (ConversionException ignored) {} 
     } 

     ... 
     if (!conversions.isSimpleType(propertyObj.getClass())) { 
      // The following line recursively calls writeInternal with the nested object 
      writePropertyInternal(propertyObj, dbo, prop); 
     } else { 
      writeSimpleInternal(propertyObj, dbo, prop); 
     } 
} 

writeInternal вызывается объект верхнего уровня, а затем рекурсивно вызывается для каждого подобъекта (aka SimpleTypes). Таким образом, они оба проходят через ту же логику добавления _id.

Возможно, это то, как мы должны читать документацию Спринга:

  • ограничения Монго на Mongo Документы:

MongoDB требует, чтобы у вас есть поле _id для всех документов. Если вы не указали , драйвер назначит ObjectId сгенерированным значением .

  • ограничения Spring Data на классы Java:

Если поле или свойство, указанное выше, не присутствует в классе Java то неявное файл _id будет вырабатываться драйвер, но не , отображаемый для свойства или поля Класс Java.

+0

Для меня это имеет смысл только в документе верхнего уровня. Почему дочерние объекты, являющиеся лишь частью документа, переводили свои значения? –

+0

Также в документации указано, что «MongoDB требует, чтобы у вас было поле _id для всех документов», а дочерние объекты НЕ являются документами. Они являются частью документа, который вставлен. –

+0

Вы отказались от меня (никаких тяжелых чувств, я согласен, я не ответил «почему»), но для записи я согласен, что это имеет смысл только на верхнем уровне. Это может быть ошибкой? – alexbt

Смежные вопросы