2016-08-29 3 views
2

私はSpring Data MongoDBプロジェクトでSpring Bootで作業していましたが、私は明確ではない動作を見ています。 idフィールドはhttp://docs.spring.io/spring-data/mongodb/docs/current/reference/html/#mapping.conventions.id-fieldごとにMongoリポジトリの_idに移動することを理解しています。私の問題は、正しいと思われない子エンティティにとっても起こっているようだということです。私はこれらのクラス(簡潔にするためにセッターとゲッターを除外)は例えばSpringでのフィールド処理Spring Data Mongo for children objects

:私は保存するために、適切なMongoRepositoryクラスを使用し

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

を、私はこれを使用してオブジェクトグラフを作成し、私は例のドキュメントで終わりますこのような(_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のリポジトリに_idに変換しています。期待されていないが、世界の終わりではない。最大の問題は、これがREST MVCによって公開され、_idフィールドがクエリから返されていないことです。私はこのクラスのために私のRepositoryRestConfigurerAdapterのexposeIdsForを設定しようとしましたが、それは最上位レベルのドキュメントのidを公開しますが、子のものは公開しません。だから私は持っている2つの質問/問題を周回

は以下のとおりです。

  • はなぜ_idにマップされ、子オブジェクトのフィールドですか?私の理解では、これはトップレベルでのみ起こるはずです。なぜなら、下にあるものは、実際には自分の権利の文書ではないからです。
  • idフィールドを公開する設定は、フィールド名をマッピングする場合、ドキュメント内の子オブジェクトに対して機能しませんか?

答えて

0

RoadSegmentにgetId()が含まれていないと誤っていますか? Spring's documentationから:

プロパティまたはフィールド注釈のないが、idという名前は_idフィールドへ マップされます。

私はSpringデータがIDフィールドを見つけたときにネストされたクラスに対してもこれを行うと信じています。フィールドがidの名前または@Fieldでそれに注釈を付けられるようにあなたは、getId()を追加することがあり、次のいずれか

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

    private String name; 
    private Double laneWidth; 
} 

を私はID/_idのこの自動変換が唯一の私の意見ではトップレベルで行われるべきである同意します。

しかし、春データMongoの変換が符号化された方法は、すべての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がオンと呼ばれていますトップレベルのオブジェクトに変換され、各サブオブジェクト(別名SimpleTypes)ごとに再帰的に呼び出されます。だから、彼らは両方とも、同じ論理の_idを追加します。

のMongoDBは、あなたがすべての文書ための_idフィールドを持っている必要があります。モンゴドキュメント

  • モンゴの制限:

    は、おそらくこれは、私たちが春のマニュアルを読むべきかです。 を指定しないと、ドライバはObjectIdに の値を割り当てます。 Javaクラスの

上記指定されていないフィールドまたはプロパティが存在しない場合は 暗黙の_idファイルはによって生成されます。

Javaクラス
  • 春データの制限ドライバではありません は、Javaクラスのプロパティまたはフィールドにマップされています。

+0

私にとってこれは最上位レベルのドキュメントでのみ意味があります。なぜドキュメントの一部である子エンティティの値が変換されるのでしょうか? –

+0

また、ドキュメントには「MongoDBでは、すべてのドキュメントに_idフィールドが必要です」というメッセージがあり、子エンティティはNOTドキュメントです。それらは挿入される文書の一部です。 –

+0

あなたは私を落胆させました。(ハードな気持ちはなく、私は「なぜ」に答えなかったのでしょうか?)しかし、記録のためには、それはトップレベルで意味をなさないことに同意します。これは非常によくバグかもしれませんか? – alexbt