简体   繁体   中英

Got Null when querying datastore by key

I have two models, Book and Chapter, in a one-to-many relationship. I manually create the keys for both Book and Chapter. To persist, I create a book object then add an instance of chapter to it and then persist book. This works fine, as I see them in the datastore. Now when I try to fetch a chapter from the datastore by key, I get a null object.

Here is how the keys look in the datastore:

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

I created my keys, both for creating and fetching objects, using

Key key = KeyFactory.createKey(Chapter.class.getSimpleName(), chapterId);

My fetching code is this:

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)

UPDATE:

I try the same thing on Book and it works fine. So the problem is with Chapter. Perhaps it's because I saved Chapter through Book (but I see both in the datastore as mentioned above).

So the question is: Is there a way to retrieve chapter independently (by its key), if yes a code snippet please.

UPDATE source code:

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


}

Code for adding:

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

mgr.persist(bk);

I did not leave any vote, but you should provide more of the surrounding code. Things mostly look fine in the code you gave, but if you created the book/chapter in a transaction (which isn't shown), the chapter may have the book specified as a parent, and you didn't specify a parent when manually creating the chapter key.

You must always include the parent entity key to retrieve the child entity. Here is how to create a key that includes the parent:

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

hope this helps.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM