Spring Data Mongo 投影忽略并覆盖保存时的值

SpringData Mongo projection ignore and overide the values on save

让我解释一下我的SpringData问题mongo,我声明了以下接口,我声明了一个自定义查询,用投影忽略索引,这个例子只是为了说明,在现实生活中我会忽略一堆字段。

public interface MyDomainRepo extends MongoRepository<MyDomain, String> {
    @Query(fields="{ index: 0 }")
    MyDomain findByCode(String code);
}

在我的 Mongo 数据库实例中,MyDomain 具有以下信息 MyDomain(code="mycode", info=null, index=19),因此当我使用 MyDomainRepo 中的 findByCode 时,我得到了以下信息 MyDomain(code="mycode", info=null, index=null) ,到目前为止一切顺利,因为这是预期的行为,但问题发生在...,我决定保存 findByCode return.

例如,在下面的示例中,我得到了 findByCode return 并将 info 属性 设置为 myinfo 并且我得到了对象吼叫。

MyDomain(code="mycode", info="myinfo", index=null)

所以我使用了 MyDomainRepo 中的 save,索引被投影预期的忽略了,但是,当我将它保存回来时,无论有没有更新,SpringData Mongo,都被覆盖了index 属性 为 null,因此,我在 MongoDB 实例上的记录也被覆盖,以下示例是我的 MongoDB JSON.

{
    "_id": "5f061f9011b7cb497d4d2708",
    "info": "myinfo",
    "_class": "io.springmongo.models.MyDomain"
}

有一种方法可以告诉 SpringData Mongo,在保存时简单地忽略空字段?

  • 保存是一个替换操作,您将无法指示它修补某些字段。它将用您发送的任何内容替换文档

  • 您的选择是使用 Spring Data Repository 提供的扩展来定义自定义存储库方法

    public interface MyDomainRepositoryCustom {
 
      void updateNonNull(MyDomain myDomain);
 
    }
   public class MyDomainRepositoryImpl implements MyDomainRepositoryCustom {
 
     private final MongoTemplate mongoTemplate;
 
     @Autowired
     public BookRepositoryImpl(MongoTemplate mongoTemplate) {
        this.mongoTemplate = mongoTemplate;
     }
 
     @Override
     public void updateNonNull(MyDomain myDomain) {
        //Populate the fileds you want to patch
        Update update = Update.update("key1", "value1")
                              .update("key2", "value2");

        // you can you Update.fromDocument(Document object, String... exclude) to
        // create you document as well but then you need to make use of `MongoConverter`  
        //to convert your domain to document. 

        // create `queryToMatchId` to mtach the id
        mongoTemplate.updateFirst(queryToMatchId, update, MyDomain.class);
     }
 
    }
    public interface MyDomainRepository extends MongoRepository<..., ...>, 
                                            MyDomainRepositoryCustom {
    }