Google app engine 按键查询数据存储时获取Null

Google app engine 按键查询数据存储时获取Null,google-app-engine,google-cloud-datastore,jpa-2.0,datanucleus,Google App Engine,Google Cloud Datastore,Jpa 2.0,Datanucleus,在一对多的关系中,我有两个模型,书和章。我手动为Book和Chapter创建键。为了持久化,我创建了一个book对象,然后向其中添加一个chapter实例,然后持久化book。正如我在数据存储中看到的那样,这很好。现在,当我尝试按键从数据存储中获取章节时,得到一个空对象 以下是密钥在数据存储中的外观: Under Book: name/id = 123 chapters = [Book(123)/Chapter("abc")] Under Chapter: name/id = abc 我

在一对多的关系中,我有两个模型,书和章。我手动为Book和Chapter创建键。为了持久化,我创建了一个book对象,然后向其中添加一个chapter实例,然后持久化book。正如我在数据存储中看到的那样,这很好。现在,当我尝试按键从数据存储中获取章节时,得到一个空对象

以下是密钥在数据存储中的外观:

Under Book: name/id = 123    chapters = [Book(123)/Chapter("abc")]
Under Chapter: name/id = abc
我使用

Key key = KeyFactory.createKey(Chapter.class.getSimpleName(), chapterId);
我的抓取代码如下:

Key key = KeyFactory.createKey(Chapter.class.getSimpleName(), chapterId);
Chapter chp = mgr.find(Chapter.class, key);//chp is always null (yes in debug mode as well)
更新:

我在书上尝试了同样的方法,效果很好。所以问题在于第二章。也许是因为我在书中保存了这一章(但我在上面提到的数据存储中看到了这两个章节)

所以问题是:有没有一种方法可以独立地(通过它的键)检索章节,如果有,请提供一个代码片段

更新源代码:

@Entity
public class Book implements java.io.Serializable{
    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Key key;

    @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
    private List<Chapter> Chapters = new ArrayList<Chapter>();

    public List<Chapter> getChapters() {
        return Chapters;
    }

    public void setChapters(List<Chapter> Chapters) {
        this.Chapters = Chapters;
    }

    public Book(long num, List<Chapter> Chapters) {
        super();
        Key key = KeyFactory.createKey(Book.class.getSimpleName(), num);
        this.key = key;
        this.Chapters = Chapters;
    }

    public Book(long num) {
        super();
        Key key = KeyFactory.createKey(Book.class.getSimpleName(), num);
        this.key = key;
    }

    public Book() {
    }

    public Key getKey() {
        return key;
    }

    public void setKey(Key key) {
        this.key = key;
    }

}



@Entity
public class Chapter implements java.io.Serializable{
    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Key key;

    private String content;

    public Chapter(String ChapterId, String content) {
        super();
        Key key = KeyFactory.createKey(Chapter.class.getSimpleName(), ChapterId);
        this.key = key;
        this.content = content;

    }


    public Key getKey() {
        return key;
    }

    public void setKey(Key key) {
        this.key = key;
    }

    public String getContent() {
        return content;
    }

    public void set content(String content) {
        this.content = content;
    }


}

我没有留下任何投票,但你应该提供更多的周围代码。在您给出的代码中,大多数情况看起来都很好,但是如果您在事务中创建了图书/章节(未显示),则章节可能将图书指定为父项,而您在手动创建章节键时没有指定父项。

必须始终包含父项实体键才能检索子实体。 以下是如何创建包含父项的密钥:

Key keyBook = KeyFactory.createKey(Book.class.getSimpleName(),
    BOOK_ID); 

Key keyChapter = KeyFactory.createKey(keyBook,
    Chapter.class.getSimpleName(), CHAPTER_ID); 

Chapter chp = mgr.find(Chapter.class, keyChapter);

希望这有帮助。

试试
mgr.find(Chapter.class,chapterId)
@PeterKnego这是我尝试的第一件事:也不起作用。似乎这个问题得到了4张赞成票和1张反对票。对于投反对票的人,如果你觉得这个问题微不足道,请你提供答案好吗?所以建议你留下评论。日志会告诉你比你说的更多。因此,您可以在“调试”模式下运行它,但将详细信息保留给您自己,如果我去拿书,我也会得到这一章。但我似乎无法单独获取章节(即使用key或id)@DataNucleus我添加了详细信息。不管我遗漏了什么细节,我认为都没有必要。我急需帮助。我不会故意提供太少的信息。感谢您离开该节点。我没有看到您在章节上调用put()将其保存到数据存储。如果两个都保存到数据存储,保存两次将引发异常。在获取代码中生成密钥时,您是否尝试指定父书本实体?我已经阅读了文档。我找到了关于将实体的键设置为其父键的文档,但没有找到关于为查询组合两个键的文档。到目前为止,我仍然有OP中出现的内容。我的困惑是:我在数据存储中看到了两个实体,每个实体都有自己的键。我能看见他们。因此,我认为必须有一种方法来访问
章节
,独立于
书籍
。本章不是嵌入式实体;它本身就存在。也许还有另一种保存和链接它们的方法。单独回复您的帖子:在python中,我不记得这种类型的查询在
ndb.Model
实体上是个问题。在JDO中,如果不使用父键,就无法检索子实体(按ID/名称)。子项密钥(id/名称)依赖于父项。按ID进行的查询只能检索一个实体,在您的情况下,如果要查找X章,则可能在N本书中。您可以尝试将手动创建的唯一长/字符串属性添加到章节中,以便进行查询以获取它们。我使用books and Chapters是因为它很方便。想象一下,章节没有编号,而是有标题,这样所有书籍中没有两个章节有相同的标题。所以让我换一种方式问这个问题:有没有一种方法可以保存这些章节,这样我在查询这本书时仍然可以得到它们,但也可以独立地查询章节?请注意,@dragonxok已经提出了您最初的建议。知道了。。。我不知道。。。我会寻找解决办法。
Key keyBook = KeyFactory.createKey(Book.class.getSimpleName(),
    BOOK_ID); 

Key keyChapter = KeyFactory.createKey(keyBook,
    Chapter.class.getSimpleName(), CHAPTER_ID); 

Chapter chp = mgr.find(Chapter.class, keyChapter);