提问者:小点点

获取sping-data-mongob以在没有支持字段的情况下尊重getter/setter?


我有一个通用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的实例,但是我有一些限制:

  1. 我不能将Spring注释添加到基类(但我可以将<code>Thing</code>子类化并对其进行注释)
  2. 我想使用name字段作为Mongodb唯一ID(主要是为了避免为其创建单独的唯一索引)
  3. 我希望(冗余地)将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,但它当然不会在Mongodb中存储名为“name”的字段。文档中说spring将使用名为“id”的“属性或字段”,或者用@id注释。因此,我尝试定义一个访问name字段的冗余getter/setter:

public class SpringThing extends Thing {
    @Id
    public String getId() {
        return super.getName();
    }
    public void setId(String id) {
        super.setName(id);
    }
}

不幸的是,Spring 在这里忽略了 getIdsetId,并使用自动生成的 ID 存储对象。我还尝试创建用 @Field(“name”)注释的冗余 getter/setter,但 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”的无意义字段。

有没有更合理的方法来得到我想要的?我想做的是合理的吗?


共1个答案

匿名用户

多亏了@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字段。