Reputation: 1316
Following structure:
@Document
public class Palace {
@Id
private String id;
private Location location;
// additional attributes, getter, setter
}
.
public class Location {
private String id;
// additional attributes, getter, setter
}
As far as I understand the concept of ObjectId, there can be only one ObjectId (_id) in a MongoDB document and it must be at the root level of the document. But when inserting data via Spring Boot 1.5.14 I get the followng structure:
{
"_id" : ObjectId("5b05387a8db58e0001d38851"),
"location" : {
"_id" : ObjectId("5ae712d1b2b197000132cd9b"),
}
}
My question is: Is this the expected behaviour in spring-data-mongo? I would have expected the following structure:
{
"_id" : ObjectId("5b05387a8db58e0001d38851"),
"location" : {
"id" : "5ae712d1b2b197000132cd9b",
}
}
If I annotate the Location id with @Field
public class Location {
@Field("id")
private String id;
// additional attributes, getter, setter
}
then the Document is saved as expected, but querying with repository method
getPalaceByLocationId()
won't give any results.
Upvotes: 2
Views: 2773
Reputation: 27018
Some insights into id
field. id field is treated a bit differently in spring-data-mongodb.
Check out the documentation.
Extending the documentation for your case, when you declare an id like this
public class Location {
private String id;
// additional attributes, getter, setter
}
It is stored as _id
in database. You can cross check by looking into the database. The same is true when you annotate it with @Id
{
"_id" : ObjectId("5b31fad36a19cc45db205056"),
"location" : {
"_id" : ObjectId("5ae712d1b2b197000132cd9b")
}
}
5ae712d1b2b197000132cd9b is the id you had set using location.setId()
. Internally it is converted to ObjectId
and stored as _id
.
But when you add @Field
annotation, things change. Let's assume you add an annotation like this
@Field("id")
private String id;
Then the document looks like this in database.
{
"_id" : ObjectId("5b31fad36a19cc45db205056"),
"location" : {
"id" : "5ae712d1b2b197000132cd9b"
}
}
With this the problem is you cannot retrieve by id. Because when you write
findPalaceByLocationId
or findByLocation_Id
it(spring-data) tries to look for _id
field which doesn't exist.
Only way around this is just use it like this
@Field
private String id;
or just
private String id;
This will create _id
in database and you can do findByLocationId
I know it is a bit sketchy. But that is how it works.
And regarding
As far as I understand the concept of ObjectId, there can be only one ObjectId (_id) in a MongoDB document and it must be at the root level of the document.
that is incorrect.
A small info table regarding mapping
Field definition Resulting Id-Fieldname in MongoDB
String id _id
@Field String id _id
@Field('x') String id x
@Field('id') String id id (InAccessible)
@Id String x _id
@Field('x') @Id String x _id
Upvotes: 1