具有自动生成的id的NullPointerException

时间:2014-11-20 03:21:49

标签: google-cloud-endpoints objectify google-app-engine

我试图将Blague实体保存到我的本地数据存储区。这是我的代码,首先是Blague模型:

@Entity
@Index
@Cache
public class Blague {
/* Enums */
@Id
private Long id;
private EnumCategory category;
private EnumType type;
private EnumLenght lenght;
private String text;
private int likes;
private int dislikes;
@Parent
private Key<User> userKey;

private Blague() {
}

public Blague(EnumCategory category, EnumType type, EnumLenght lenght, String text,
        Key<User> user) {
        /* assignation but no for id*/
        }
/* Constructors */

用户可以拥有许多将用户作为父级

的blagues
/* the sames @ than Blague */
public class User {
@Id
private Long id;
private String name;

private User() {}

public User(String name){
    this.name = name;
}
/* Constructors */

然后,blagues可以有关键字:

/* the sames @ than Blague */
public class KeyWord {
@Id
private Long id;
private String word;
@Parent
private Key<Blague> blagueKey;

private KeyWord() {}

public KeyWord(String word, Key<Blague> blague) {
    /* assignation but no for id*/
}
/* constructors*/

我使用EndPoint通过POST方法将Blague实体插入数据存储区。为此,我在userId参数中创建了一个userKey(此用户已经存储)。然后我创建一个blague,将其存储在数据库中。最后,我从列表中的字符串创建关键字实体,并将之前的blague设置为其父级。这是我的代码:

@ApiMethod(
    name = "addBlague",
    path = "addBlague",
    httpMethod = ApiMethod.HttpMethod.POST)
public void addBlague(
    @Named("category") EnumCategory category,
    @Named("type") EnumType type,
    @Named("lenght") EnumLenght lenght,
    @Named("keywords") List<String> keywords,
    @Named("text") String text,
    @Named("userId") Long userId){
Key<User> userKey = Key.create(User.class, userId);
Blague blague = new Blague(category, type, lenght, text, userKey);
ofy().save().entity(blague);
System.out.println(blague.getId());

/**********NullPointerExcecption**************/
Key<Blague> blagueKey = Key.create(Blague.class, blague.getId());

for (String word : keywords) {
    KeyWord keyword = new KeyWord(word, blagueKey);
    ofy().save().entity(keyword);
}
}

我的问题是,当我试图创建blague的密钥时,我有一个NullPointerException。我检查了调试器中实体内容的值,我发现blague的id为null。为什么不生成它?

此外,存储了blague并且它的id存在。当我启动数据存储区查看器时,我可以看到我的blague实体及其id在Id / Name列中存储为一个大数字。为什么它是空的?

我还检查了调试器中的User实体,除了id之外,值为null。为什么?我将在dataviewer中找到的用户ID设置为API方法的参数。

感谢您的帮助

2 个答案:

答案 0 :(得分:1)

在appengine中,实体没有id。它有一个Key,而Key有一个id。

要检索“实体的ID”,您必须先获取其密钥。然后你可以获得Key的ID:

blague.getKey().getId() // retrieves the id

请参阅Entity.getKey()Key.getId()

答案 1 :(得分:0)

感谢您的回答,但我使用Objectify并且blague是Blague类型而不是实体。它包含要存储的anotation @Entity和一个自动生成的id(@Id Long id)。

我找到了解决方案。 id为null,因为它尚未生成。 当我们保存实体时生成id,所以当我这样做时:

ofy().save().entity(blague);

这个异步方法在操作完成之前没有生成id,所以当我尝试调用blague.id时,它还没有。 我这样做是为了进行同步保存并且工作正常:

ofy().save().entity(blague).now();