Skartt
Skartt

Reputation: 591

NullPointerException with auto-generated id

I'm trying to save the Blague entity to my local datastore. Here is my code and first the Blague model :

@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 */

an user can have numerous blagues which have a user as parent

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

private User() {}

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

Then, the blagues can have keywords :

/* 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*/

I'm using EndPoint to insert a Blague entity to the datastore via a POST method. For doing that, I create an userKey from the userId in parameters (this user is already stored). Then I create a blague, store it in the database. Finally, I create the keywords entity from the strings in the list and set the previous blague as their parent. Here is my code :

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

My problem is that I have a NullPointerException when i'm trying to create the blague's key. I checked the values of entities's content in the debugger and I saw that the blague's id is null. Why isn't it generated ?

Moreover, the blague is stored and its id exist. When I launch the datastore viewer, I can see my blague entity and its id stored as a big number in the Id/Name column. Why is it null ?

I also checked the User entity in the debugger and the values are null except the id. Why ? I set the user id found in the dataviewer to the API method's parameter.

Thanks for your help

Upvotes: 0

Views: 186

Answers (2)

Skartt
Skartt

Reputation: 591

Thanks for your answer, but I'm using Objectify and blague is of type Blague and not Entity. It contains the anotation @Entity to be stored and an auto-generated id (@Id Long id).

I found the solution. The id was null because it wasn't generated yet. The id is generated when we save the entity so when I did :

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

This asynchronous method didn't generate the id until the operation is completed, so when I tryed to call blague.id, it didn't yet. I did that to make a synchronous save and it worked :

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

Upvotes: 0

Tim
Tim

Reputation: 43304

In appengine, an Entity does not have an id. It has a Key, and that Key has an id.

In order to retrieve an 'Entity's id', you must first get its Key. Then you can get the Key's id:

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

See Entity.getKey() and Key.getId()

Upvotes: 1

Related Questions