Java 如何通过Google云数据存储JSON API存储带有子类的类?

Java 如何通过Google云数据存储JSON API存储带有子类的类?,java,json,google-cloud-datastore,Java,Json,Google Cloud Datastore,为了存储到GCD中,我想使用,但无法为具有另一个类成员的对象编写正确的Json请求体。考虑我有 2 类: public class Foo { private String id; private Bar bar; // getter and setter... } public class Bar { private String name; private String pass; // getter and setter... } 然后我

为了存储到GCD中,我想使用,但无法为具有另一个类成员的对象编写正确的
Json
请求体。考虑我有<代码> 2 <代码>类:

public class Foo {
    private String id;
    private Bar bar;
    // getter and setter...
}

public class Bar {
    private String name;
    private String pass;
    // getter and setter...
}
然后我创建一个
Foo
class的对象,其中包含一个
Bar
class的对象。 所以我想把这个对象插入云数据存储。我写了这个请求:

{
  "transaction":"some bytes",
  "mutation":{
    "insert":[
      {
        "key":{
          "partitionId":{
            "datasetId":"s~my-dataset-id"
          },
          "path":[
            {
              "kind":"Foo",
              "name":"id"
            }
          ]
        },
        "properties":{
          "bar":{
            "entityValue":{
              "name":{
                "stringValue":"Jack"
              },
              "pass":{
                "stringValue":"1234"
              }
            },
            "indexed":false
          },
          "id":{
            "stringValue":"id"
          }
        }
      }
    ]
  }
}
然后,除
bar
之外的所有字段都将保存到云数据存储中。我使用了“entityValue”,但似乎应该包括整个实体结构(感谢Adam提到它)。但我不需要它作为另一个实体,显然我不应该使用“entityValue”。 那么我应该如何更改请求主体以插入这样一个对象呢

顺便说一下,我可以通过以下请求插入
对象(但不是
Foo
):

   {
  "transaction":"some bytes",
  "mutation":{
    "insert":[
      {
        "key":{
          "partitionId":{
            "datasetId":"s~my-project-id"
          },
          "path":[
            {
              "kind":"Bar",
              "name":"John"
            }
          ]
        },
        "properties":{
          "pass":{
            "stringValue":"1234"
          },
          "name":{
            "stringValue":"John"
          }
        }
      }
    ]
  }
}

这是相关链接:

您必须包含“entityValue”的整个实体结构(包括“key”和“properties”字段)。这是因为您引用的是数据存储中的一个单独实体,而不仅仅是嵌入在当前实体中的另一个数据结构。见:

数据集:实体格式


字段“entityValue”:(实体)'提示您需要从新实体的相同实体表示的开头开始。

您可以将
Bar
包含为
entityValue
。此值看起来像普通实体,但不需要有键。此实体值不需要单独存在于数据存储中

例如:

{
  "mutation":{
    "insert":[
      {
        "key":{
          "path":[
            {
              "kind":"Foo",
              "name":"id"
            }
          ]
        },
        "properties":{
          "bar":{
            "entityValue":{
              "properties": {
                "name":{
                  "stringValue":"Jack"
                },
                "pass":{
                  "stringValue":"1234"
                }
              }
            },
            "indexed":false
          },
          "id":{
            "stringValue":"id"
          }
        }
      }
    ]
  },
  "mode": "NON_TRANSACTIONAL"
}

另请注意,这里的
Foo
键省略了
partitionId
。这是首选操作,数据存储将为您填写正确的
partitionId

您是对的。我认为“entityValue”“可以处理嵌入的类对象,但我不需要它作为另一个实体,所以我应该如何更改请求主体?”?(我将编辑我的问题)如果您只想将子类存储为某个实体的内联属性,那么最好是手动序列化它并将原始JSON存储为嵌入的StringProperty。嵌入式实体仍然需要密钥,否则它不是实体。在数据存储中引用它是不可能的,它区别于其他实体的一些属性(很像C++中的,你可以自己引用类‘bar’)。执行时是否收到错误消息?当我尝试存储Foo类的对象时,没有为嵌入的Bar对象保存任何内容。您如何检索Bar对象?我检查了google cloud Data store()和其他字段是否有值,但Bar对象没有值。您能提供一个屏幕截图吗(您可以将其发送到我个人资料上的电子邮件地址)?当我尝试复制此内容时,我看到实体属性显示消息“编辑此类型不受支持”谢谢。它工作得很好。
bar
对象保存为JSON字符串,但我需要另一种形式!有办法查询它们吗?还没有--您不能查询单个字段,因为
entityValue
标记为
“索引”:false
。我们正在积极支持索引实体值。然后您可以将其与
“indexed”:true一起放置,并查询特定属性,如
bar.name==“Jack”
。如果您现在想这样做,可以存储一个名为“bar.name”的单独属性用于要查询的属性。当实体值支持索引时,可以更新代码以使用索引实体值属性。