获取 spring-data-mongodb 以在没有支持字段的情况下兑现 getter/setter?
Get spring-data-mongodb to honor getter/setter without backing field?
我有一个通用的 POJO:
public class Thing {
private String name;
private String etc;
public String getName() {
return name;
}
// other getters and setters
}
我正在使用 Spring 4.3.9 和 Spring-data-mongodb 1.10.4。我想在 Mongodb 中存储此 POJO 的实例,但我有一些限制:
- 我无法向基础 class 添加 Spring 注释(但我可以子class
Thing
并对其进行注释)。
- 我想使用
name
字段作为Mongodb唯一ID(主要是为了避免为其创建单独的唯一索引)。
- 我想(冗余地)将
name
字段存储为名为 "name" 的实际字段,以便该集合的其他消费者不必知道 "name" 是存储在 _id
.
我开始尝试这个:
public class SpringThing extends Thing {
@Id
@Override
public String getName() {
return super.getName();
}
@Override
public void setName(String name) {
super.setName(name);
}
}
这导致spring将name
的值用于_id
,当然它不会在[=63=中存储一个名为"name"的字段]. The documentation 表示 spring 将使用名为 "id" 或注释为 @Id
的 "property or field"。所以我尝试定义一个冗余的 getter/setter 来访问名称字段:
public class SpringThing extends Thing {
@Id
public String getId() {
return super.getName();
}
public void setId(String id) {
super.setName(id);
}
}
不幸的是,spring 在这里忽略了 getId
和 setId
,并使用自动生成的 ID 存储对象。我还尝试创建用 @Field("name")
注释的冗余 getters/setters,但是 spring 似乎忽略了任何没有实际字段的 getter/setter 对。
添加一个实际的 ID 字段并在那里存储名称的副本确实有效:
public class SpringThing extends Thing {
@Id
private String id;
@Override
public void setName(String id) {
this.id = id;
super.setName(id);
}
}
但它需要定义一个无意义的字段,名称为"id"。
有没有更合理的方式得到我想要的?我想做的事情一开始就合理吗?
感谢@mp911de 的提示,我最终创建了 Thing
的子类,如下所示:
@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
注释覆盖了 spring 将用于类型的名称,以掩盖我创建子类只是为了添加注释的事实。
@Id
表示这是 _id
的 getter。
@AccessType
表示通过 getter 和 setter 访问此字段,而不是直接访问该字段。这就是我需要的;没有它,spring 会寻找一个名为 id
. 的私有成员变量
@JsonIgnore
是 Jackson(我们正在使用的 JSON 库)注释,用于防止在将这些对象序列化为 JSON 时包含 id
字段。
我有一个通用的 POJO:
public class Thing {
private String name;
private String etc;
public String getName() {
return name;
}
// other getters and setters
}
我正在使用 Spring 4.3.9 和 Spring-data-mongodb 1.10.4。我想在 Mongodb 中存储此 POJO 的实例,但我有一些限制:
- 我无法向基础 class 添加 Spring 注释(但我可以子class
Thing
并对其进行注释)。 - 我想使用
name
字段作为Mongodb唯一ID(主要是为了避免为其创建单独的唯一索引)。 - 我想(冗余地)将
name
字段存储为名为 "name" 的实际字段,以便该集合的其他消费者不必知道 "name" 是存储在_id
.
我开始尝试这个:
public class SpringThing extends Thing {
@Id
@Override
public String getName() {
return super.getName();
}
@Override
public void setName(String name) {
super.setName(name);
}
}
这导致spring将name
的值用于_id
,当然它不会在[=63=中存储一个名为"name"的字段]. The documentation 表示 spring 将使用名为 "id" 或注释为 @Id
的 "property or field"。所以我尝试定义一个冗余的 getter/setter 来访问名称字段:
public class SpringThing extends Thing {
@Id
public String getId() {
return super.getName();
}
public void setId(String id) {
super.setName(id);
}
}
不幸的是,spring 在这里忽略了 getId
和 setId
,并使用自动生成的 ID 存储对象。我还尝试创建用 @Field("name")
注释的冗余 getters/setters,但是 spring 似乎忽略了任何没有实际字段的 getter/setter 对。
添加一个实际的 ID 字段并在那里存储名称的副本确实有效:
public class SpringThing extends Thing {
@Id
private String id;
@Override
public void setName(String id) {
this.id = id;
super.setName(id);
}
}
但它需要定义一个无意义的字段,名称为"id"。
有没有更合理的方式得到我想要的?我想做的事情一开始就合理吗?
感谢@mp911de 的提示,我最终创建了 Thing
的子类,如下所示:
@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
注释覆盖了 spring 将用于类型的名称,以掩盖我创建子类只是为了添加注释的事实。@Id
表示这是_id
的 getter。@AccessType
表示通过 getter 和 setter 访问此字段,而不是直接访问该字段。这就是我需要的;没有它,spring 会寻找一个名为id
. 的私有成员变量
@JsonIgnore
是 Jackson(我们正在使用的 JSON 库)注释,用于防止在将这些对象序列化为 JSON 时包含id
字段。