Reputation: 25399
I have a general-purpose POJO:
public class Thing {
private String name;
private String etc;
public String getName() {
return name;
}
// other getters and setters
}
I'm using Spring 4.3.9 and Spring-data-mongodb 1.10.4. I want to store instances of this POJO in Mongodb, but I have some constraints:
Thing
and annotate that).name
field as the Mongodb unique ID (mainly to avoid creating a separate unique index for it).name
field as an actual field named "name", so that other consumers of the collection don't have to know that "name" is stored in the _id
.I started out trying this:
public class SpringThing extends Thing {
@Id
@Override
public String getName() {
return super.getName();
}
@Override
public void setName(String name) {
super.setName(name);
}
}
This causes spring to use the value of name
for _id
, but of course it doesn't store a field named "name" in Mongodb. The documentation says that spring will use a "property or field" named "id" or annotated with @Id
. So I tried defining a redundant getter/setter which accesses the name field:
public class SpringThing extends Thing {
@Id
public String getId() {
return super.getName();
}
public void setId(String id) {
super.setName(id);
}
}
Unfortunately, spring ignores getId
and setId
here, and stores the object with an autogenerated ID. I also tried creating redundant getters/setters annotated with @Field("name")
, but spring seems to ignore any getter/setter pair without an actual field.
Adding an actual ID field and storing a copy of the name there does work:
public class SpringThing extends Thing {
@Id
private String id;
@Override
public void setName(String id) {
this.id = id;
super.setName(id);
}
}
But it requires defining a pointless field named "id".
Is there a more reasonable way to get what I want? Is what I'm trying to do reasonable to begin with?
Upvotes: 4
Views: 4614
Reputation: 25399
Thanks to a hint by @mp911de, I ended up creating a subclass of Thing
that looks like this:
@TypeAlias("thing")
@Document(collection = "things")
public class SpringThing extends Thing {
@Id
@AccessType(Type.PROPERTY)
@JsonIgnore
public String getId() {
return super.getName();
}
public void setId(String taskName) {
super.setName(taskName);
}
}
@TypeAlias
annotation overrides the name which spring would use for the type, to cover up the fact that I've created a subclass just to add annotations.@Id
says that this is the getter for _id
.@AccessType
says to access this field through the getter and setter rather than by directly accessing the field. This is what I needed; without it, spring looks for a private member variable named something like id
.@JsonIgnore
is the Jackson (JSON library that we're using) annotation to prevent including the id
field when serializing these objects to JSON.Upvotes: 9