Rob*_*ily 5 spring-boot spring-mongodb
我一直在 Spring Boot 中使用 Spring Data MongoDB 项目,我看到了一些我不清楚的行为。我知道 id 字段将转到 Mongo 存储库中的 _id http://docs.spring.io/spring-data/mongodb/docs/current/reference/html/#mapping.conventions.id-field。我的问题是,子实体似乎也发生了这种情况,这似乎不正确。
例如,我有这些类(为简洁起见,省略了 setter 和 getter):
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;
}
Run Code Online (Sandbox Code Playgroud)
我使用它创建一个对象图我使用适当的 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
}
]
}
}
Run Code Online (Sandbox Code Playgroud)
在本例中,具有名为 id 字段的子对象的映射转换为 MongoDB 存储库中的 _id。虽然没有预料到,但并不是世界末日。现在最大的问题是 REST MVC 暴露了 _id 字段不会从查询中返回。我尝试在我的 RepositoryRestConfigurerAdapter 中为此类设置 ExposureIdsFor,它公开了顶级文档的 id,但不公开子文档的 id。
因此,围绕我的两个问题/问题是:
我认为 RoadSegment 不包含 a 是错误的吗getId()?来自Spring 的文档:
\n\n\n没有注释但名为 id 的属性或字段将映射\n 到 _id 字段。
\n
我相信当 Spring Data 找到 id 字段时,它甚至会对嵌套类执行此操作。您可以添加一个getId(),以便该字段被命名id或使用注释@Field:
public class RoadSegment {\n @Field("id")\n private int id;\n\n private String name;\n private Double laneWidth;\n}\nRun Code Online (Sandbox Code Playgroud)\n\n我同意在我看来这种 id/_id 的自动转换应该只在顶层完成。
\n\n然而,Spring Data Mongo 转换的编码方式,所有 java 对象都会经过精确的转换代码来转换为 json(顶级对象和嵌套对象):
\n\npublic class MappingMongoConverter {\n...\n protected void writeInternal(Object obj, final DBObject dbo, MongoPersistentEntity<?> entity) {\n ...\n if (!dbo.containsField("_id") && null != idProperty) {\n try {\n Object id = accessor.getProperty(idProperty);\n dbo.put("_id", idMapper.convertId(id));\n } catch (ConversionException ignored) {}\n }\n\n ...\n if (!conversions.isSimpleType(propertyObj.getClass())) {\n // The following line recursively calls writeInternal with the nested object\n writePropertyInternal(propertyObj, dbo, prop); \n } else {\n writeSimpleInternal(propertyObj, dbo, prop);\n }\n}\nRun Code Online (Sandbox Code Playgroud)\n\nwriteInternal在顶级对象上调用,然后为每个子对象(也称为 SimpleTypes)递归调用。所以他们都经历了相同的添加逻辑_id。
也许这就是我们应该如何阅读 Spring 的文档:
\n\n\n\n\nMongoDB 要求所有文档都有一个 _id 字段。如果您不\n\n\xe2\x80\x99 提供一个,驱动程序将使用生成的\n 值分配一个ObjectId。
\n
\n\n如果Java 类中不存在上面指定的字段或属性,则驱动程序将生成隐式 _id 文件,但不会映射到Java 类的属性或字段。
\n
| 归档时间: |
|
| 查看次数: |
6573 次 |
| 最近记录: |