4

我有两种模式,书和章,采用一对多的关系。我手动创建Book和Chapter的键。坚持下来,我创建一个书对象,然后添加一个章节的实例,然后坚持书。这很好,因为我在数据存储中看到它们。现在,当我试图通过键从数据存储中获取一章时,我得到一个空对象。通过键查询数据存储库时无效

这里是关键如何看待在数据存储:

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) 

更新:

我在书上尝试同样的事情,它工作正常。所以问题在于章节。也许这是因为我通过Book保存了章节(但我在上面提到的数据存储中都可以看到)。

所以问题是:有没有一种方法来独立检索章节(通过它的关键),如果是的话,一个代码段请。

更新源代码:

@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; 
    } 


} 

代码添加:

Book bk = new Book(num); 
     Chapter chp = new Chapter(ChapterId, content); 
     bk.getChapters().add(chp); 
     bookDao.put(bk); 

mgr.persist(bk); 
+0

尝试'mgr.find(Chapter.class,chapterId)' – 2013-04-06 12:02:40

+0

@PeterKnego这是我尝试的第一件事:也不管用。 – learner 2013-04-06 12:13:14

+0

看来这个问题得到4票和1票反对票。对于那些倒票的人,如果你觉得这个问题微不足道,你能否提供答案? SO建议您发表评论。 – learner 2013-04-06 12:41:45

回答

1

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

+0

@DataNucleus我已经添加了详细信息。无论我忽略了哪些细节,我认为这是不必要的。我迫切需要帮助。我不会根据目的提供太少的信息。感谢您离开节点。 – learner 2013-04-06 17:47:50

+0

我看不到你在该章节调用put()将其保存到数据存储区。 – dragonx 2013-04-06 18:51:41

+0

都保存到数据存储区,保存两次会引发异常。 – learner 2013-04-06 18:54:39

0

您必须始终包含父实体键以检索子实体。 下面是如何创建一个包含父键:

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); 

希望这会有所帮助。

+0

我的困惑是:我在数据存储中看到两个实体,每个实体都有自己的密钥。我可以看到他们。所以我想,必须有一种方法可以独立于'Book'来访问'Chapter'。本章不是一个嵌入式实体;它本身存在。也许还有另一种方法来保存和链接它们。要单独回复你的帖子:在python中,我不记得这种类型的查询是'ndb.Model'实体的问题。所以必须有一种方法可以在Java中完成。 – learner 2013-04-08 19:01:13

+0

在JDO中,您无法使用父键检索子实体(按ID/NAME)。子键(id /名称)依赖于父级。通过ID查询只能检索一个实体,对于你的情况,如果你正在寻找一个X章,这可能是在N本书中。 – 2013-04-08 19:57:36

+0

你可以尝试添加一个手动创建的唯一长/字符串属性到你的章节,所以你可以让查询来获得它们。 – 2013-04-08 19:59:15