【问题标题】:Get spring-data-mongodb to honor getter/setter without backing field?让 spring-data-mongodb 在没有支持字段的情况下尊重 getter/setter?
【发布时间】:2017-06-28 20:04:16
【问题描述】:

我有一个通用的 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 注释添加到基类(但我可以继承 Thing 并对其进行注释)。
  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”的字段。 The documentation 表示 spring 将使用名为“id”或使用 @Id 注释的“属性或字段”。所以我尝试定义一个冗余的 getter/setter 来访问 name 字段:

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”的无意义字段。

有没有更合理的方式来获得我想要的东西?我开始尝试做的事情是否合理?

【问题讨论】:

  • 您是否尝试将@AccessType 添加到您的 Spring 特定类?或者,如果该模式适合您,您可以将无法更改的类存储为嵌套文档。
  • @mp911de 我不知道 AccessType 注释。我尝试将它添加到 getId/setId 尝试中,它具有预期的效果——spring 使用 getId/setId 作为唯一 ID。如果你把它写下来作为答案,我会接受。
  • 如果您找到了解决方案,想添加答案吗?看到一个完整的例子会非常有用。
  • @woemler 添加了答案。希望有用!

标签: spring-data-mongodb


【解决方案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 的吸气剂。
  • @AccessType 表示通过 getter 和 setter 访问该字段,而不是直接访问该字段。这就是我所需要的;没有它,spring 会寻找一个名为 id 的私有成员变量。
  • @JsonIgnore 是 Jackson(我们正在使用的 JSON 库)注解,用于防止在将这些对象序列化为 JSON 时包含 id 字段。

【讨论】:

    猜你喜欢
    • 2019-03-01
    • 2017-06-11
    • 1970-01-01
    • 1970-01-01
    • 2022-07-23
    • 1970-01-01
    • 2017-02-09
    • 2021-12-07
    • 1970-01-01
    相关资源
    最近更新 更多