简体   繁体   English

Spring Mongo 存储库无法将字符串与 _id 字段中的 ObjectId 匹配

[英]Spring Mongo Repository is unable to match String to ObjectId in _id field

I have a data class with a String Id and I'm saving it into the mongoDB with a null value to get an autogenerated replacement.我有一个带有字符串 ID 的数据 class ,我将其保存到 mongoDB 中,并带有 null 值以获得自动生成的替换。

@Document(collection="applications")
@TypeAlias(Constants.Application)
public class DataApplication implements IApplication{

@Id
@Field("id")
private String id = null;

...
}

This works as expected however I'm facing a problem in that I cannot seem to findById from the Spring Mongo Repo.这可以按预期工作,但是我面临一个问题,因为我似乎无法从 Spring Mongo Repo 中找到 findById。 It is capable of persisting and retrieving without problems, creating BSON like它能够毫无问题地持久化和检索,创建类似 BSON

{
   "_id" : ObjectId("5ef9a579bafa09b36225e743c"),
   Other fields and things
}

However, this seems to be specifically about when attempting to find using the id field.但是,这似乎专门针对尝试使用 id 字段进行查找时。 Its very weird that it isn't using the Id field name I specified, however as when I retrieve multiple objects at once they convert back into POJOs as expected I do not believe this is an issue.它没有使用我指定的 Id 字段名称,这很奇怪,但是当我一次检索多个对象时,它们按预期转换回 POJO,我不认为这是一个问题。

From what I can see this seems to be a result of the MongoDB storing the values as ObjectId's, as I am able to retrieve by Id when I persist an object with a String Id value, when I pull the Applications into Java to compare, or when I create Examples that match all fields except Id, however Examples fails when I set an Id to compare against.据我所知,这似乎是 MongoDB 将值存储为 ObjectId 的结果,因为当我将应用程序拉入 ZD52387880E371EA223817A7 进行比较时,当我将 object 与字符串 ID 值保持一致时,我可以通过 Id 检索当我创建匹配除 ID 之外的所有字段的示例时,但是当我设置要比较的 ID 时,示例失败。

Prevent Spring Data for Mongo to convert ids to ObjectId seems to be related as it mentions the underlying query structure, unfortunately I seem to have the opposite problem. 阻止 Spring Data for Mongo 将 ids 转换为 ObjectId似乎是相关的,因为它提到了底层查询结构,不幸的是我似乎有相反的问题。

@Field annotation is used to define custom metadata for document fields. @Field注解用于定义文档字段的自定义元数据。 For example:例如:

@Field(targetType = DECIMAL128)
private BigDecimal value;

@Field("fName")
private String firstName;

When you defined @Field("id") private String id = null;当您定义@Field("id") private String id = null; it is interpreted as the field id as another field id not the document identifier field _id .它被解释为字段id作为另一个字段id而不是文档标识符字段_id Because, the annotation's name attribute is specified as "id".因为,注解的name属性被指定为“id”。 You can verify this as well in the following example using the Person Pojo class:您也可以使用Person Pojo class 在以下示例中验证这一点:

public class Person {
    
    @Field("id")
    private String id = null;

    private String name;
    
    public Person(String name) {
        this.name = name;
    }

    public void setId(String id) {
        this.id = id;
    }

    // other get / set methods ...

    public String toString() {
       return "id: " + id + ", " + name;
    }
}

Using MongoRepository methods insert and query documents in person collection:使用MongoRepository方法在person集合中插入和查询文档:

Person p1 = new Person("J.Doe");
//p1.setId("000");
repo.insert(p1);

List<Person> list = repo.findAll();
list.forEach(System.out::println);

This will insert a document (as queried from the mongo shell) and print the toString representation as:这将插入一个文档(从mongo shell 查询)并将toString表示打印为:

{ "_id" : ObjectId("5ef5c92b70babc5a961350e5"), "name" : "J.Doe", "_class" : "com.example.demo.Person" }

Prints as: id: null, J.Doe打印为: id: null, J.Doe

If you un-comment the code p1.setId("000");如果您取消注释代码p1.setId("000"); and run it again, you will find the following:再次运行它,你会发现以下内容:

{ "_id" : ObjectId("5ef5cab8306d071b13d3c16e"), "id" : "000", "name" : "J.Doe", "_class" : "com.example.demo.Person" }

And, prints as: id: 000, J.Doe并且,打印为: id: 000, J.Doe

The code is behaving alright.代码运行良好。 Note the two fields, the _id and id .注意两个字段, _idid The @Field is to be used for customizing a document field. @Field用于自定义文档字段。

To properly indicate the id field is to be used for _id document key field you can use the following.要正确指示id字段将用于_id文档键字段,您可以使用以下内容。 When the document is created the _id value will be the driver generated ObjectId :创建文档时, _id值将是驱动程序生成的ObjectId

  • Annotate the id field as @Id , @MongoId or the @Field (without the name attribute).id字段注释为@Id@MongoId@Field (没有name属性)。
  • Not annotate at all.根本不注释。

Note on Annotations:注解注意事项:

  • @Id : Applied at the field level to mark the field used for identity purpose. @Id :应用于字段级别以标记用于标识目的的字段。
  • @MongoId : Applied at the field level to mark the field used for identity purpose. @MongoId :应用于字段级别以标记用于标识目的的字段。 Accepts an optional FieldType to customize id conversion.接受可选的 FieldType 来自定义 id 转换。
  • @Field: Applied at the field level it allows to describe the name and type of the field as it will be represented in the MongoDB BSON document thus allowing the name and type to be different than the field name of the class as well as the property type. @Field:应用于字段级别,它允许描述字段的名称和类型,因为它将在 MongoDB BSON 文档中表示,因此允许名称和类型不同于 class 的字段名称以及属性类型。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM