MongoDB Panache 更新文档中的嵌套对象

MongoDB Panache Updating nested objects within Document

我有一个看起来像这样的模型:

{
  "projectName": "MyFirstProject",
  "projectId": "1234",
  "testCaseList": [
    {
      "testCaseName": "TestCase1",
      "steps": [
        {
          "Action": "Click on this",
          "Result": "pass"
        },
        {
          "Action": "Click on that",
          "Result": "pass"
        }
      ]
    },
    {
      "testCaseName": "TestCase2",
      "steps": [
        {
          "Action": "Click on him",
          "Result": "pass"
        },
        {
          "Action": "Click on her",
          "Result": "pass"
        }
      ]
    }
  ]
}

但是,由于这是一个嵌套对象,我在使用以下方法更新它时遇到困难:

default PanacheUpdate update(String update, Object... params)

我正在使用存储库模式,下面是我的代码片段:

List<TestCase> newTestCaseList = ...;
update("testCaseList", newTestCaseList).where("projectId=?1",projectId);

实际上抛出以下错误:

org.bson.json.JsonParseException: JSON reader was expecting ':' but found ','.
at org.bson.json.JsonReader.readBsonType(JsonReader.java:149)
    at org.bson.codecs.BsonDocumentCodec.decode(BsonDocumentCodec.java:82)
    at org.bson.codecs.BsonDocumentCodec.decode(BsonDocumentCodec.java:41)
    at org.bson.codecs.BsonDocumentCodec.readValue(BsonDocumentCodec.java:101)
    at org.bson.codecs.BsonDocumentCodec.decode(BsonDocumentCodec.java:84)
    at org.bson.BsonDocument.parse(BsonDocument.java:63)
    at io.quarkus.mongodb.panache.runtime.MongoOperations.executeUpdate(MongoOperations.java:634)
    at io.quarkus.mongodb.panache.runtime.MongoOperations.update(MongoOperations.java:629)

我目前的做法

目前对我有用的是在更新嵌套对象时使用 default void update(Entity entity)。 然而,这提出了一些注意事项:

  1. 需要额外的代码来获取整个文档、解析并更新所需的字段
  2. 由于 update(Entity entity) 在文档级别工作,它还会更新文档中未更改的部分,这并不理想。

我猜遇到的错误只是说明 mongoDB 目前通过提供的标准 PanacheQL 的 Panache 的限制.

应该使用本机 mongoDB Java API 来解决这个问题,可以通过 PanacheMongoEntityBase#mongoCollection :

mongoCollection().updateOne(
        eq("projectId", projectId),
        new Document("$set", new Document("testCaseList", newTestCaseList))
);