Исключение нулевого указателя NPE в Ябе - PullRequest
1 голос
/ 28 июля 2011

Я работаю над учебным пособием по Yabe и столкнулся с некоторым исключением из-за нулевого указателя при тестовом использованииTheCommentsRelation

useTheCommentsRelation

A java.lang.NullPointerException has been caught, null
In /test/BasicTest.java, line 96 :

 bobPost.addComment("Jeff", "Nice post"); 
 Hide tracejava.lang.NullPointerException
at models.Post.addComment(Post.java:30)
at BasicTest.useTheCommentsRelation(BasicTest.java:96)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)

Вот код теста;

@Test
public void useTheCommentsRelation() {
    // Create a new user and save it
    User bob = new User("bob@gmail.com", "secret", "Bob").save();

    // Create a new post
    Post bobPost = new Post(bob, "My first post", "Hello world").save();

    // Post a first comment
    bobPost.addComment("Jeff", "Nice post");
    bobPost.addComment("Tom", "I knew that !");

    // Count things
    assertEquals(1, User.count());
    assertEquals(1, Post.count());
    assertEquals(0, Comment.count()); // 2 when correct not 0

    // Retrieve Bob's post
    bobPost = Post.find("byAuthor", bob).first();
    assertNotNull(bobPost);

    // Navigate to comments
    assertEquals(2, bobPost.comments.size()); 
    assertEquals("Jeff", bobPost.comments.get(0).author);

    // Delete the post
    bobPost.delete();

    // Check that all comments have been deleted
    assertEquals(1, User.count());
    assertEquals(0, Post.count());
    assertEquals(0, Comment.count());
}

а вот класс Post с методом addComment в конце.

package models;

import java.util.*;
import javax.persistence.*;

import play.db.jpa.*;

@Entity
public class Post extends Model{

public String title;
public Date postedAt;

@Lob
public String content;

@ManyToOne
public User author;

@OneToMany(mappedBy="post", cascade=CascadeType.ALL)
public List<Comment> comments;  
public Post(User author, String title, String content){
    this.author = author;
    this.title = title;
    this.content = content;
    this.postedAt = new Date();
}
public Post addComment(String author, String content) {
    Comment newComment = new Comment(this, author, content).save();
    this.comments.add(newComment);
    this.save();
    return this;
}
}

Класс комментариев

package models;

import java.util.*;
import javax.persistence.*;
import play.db.jpa.*;

@Entity
public class Comment extends Model{
public String author;
public Date postedAt;
@Lob
public String content;
@ManyToOne
public Post post;
public Comment(Post post, String author, String content){
    this.post = post;
    this.author = author;
    this.content = content;
    this.postedAt = new Date();
}
}

Спасибо всем, кто зашел так далеко.

Ответы [ 4 ]

4 голосов
/ 28 июля 2011

Я не вижу, чтобы Post.comments где-либо инициализировался, но addComment () пытается разыменовать его с помощью this.comments.add(...).

1 голос
/ 30 июля 2011

Ответ, своего рода, Полная правильная версия Yabe включена в установку в
play_installation] samples-and-tests
Если вы когда-либо слишком запутались, вы можете сравнить и сравнить, чтобы увидеть, где вы ошиблись.

0 голосов
/ 28 ноября 2011

Я знаю, что вы как бы сами ответили, предоставив общий совет, чтобы пойти и посмотреть примеры кода в вашей игре! установка, но для кого-то еще это может быть полезно:

@ RyanStewart прав, вам нужно инициализировать "Post.comments".

На самом деле написано в учебном пособии, но это действительно легко пропустить (я сам сделал это, и я слишком привык к любезности Джанго, чтобы делать все сам, чтобы понять, что, возможно, придется инициализировать это сам!)

public Post(User author, String title, String content) {
...
    this.comments = new ArrayList<Comment>();
...
0 голосов
/ 28 июля 2011

РЕДАКТИРОВАТЬ: я сделал тест дома, небольшая разница между исходным ответом и новым:

  • Я не заметил Список в вашем коде, так как он слишком близок к конструктору.Мой плохой!
  • Я забыл добавить метод обновления, чтобы получить новое состояние из базы данных на объекте

Изменить метод:

public Post addComment(String author, String content) {
    Comment newComment = new Comment(this, author, content).save(); //adds the comment
    return this.refresh(); //tell Hibernate to get the latest state from the DB
}

Этосохранит комментарий правильно.Тестовый код:

@Test
    public void useTheCommentsRelation() {
        // Create a new user and save it
        UserT bob = new UserT("bob@gmail.com", "secret", "Bob").save();

        // Create a new post
        Post bobPost = new Post(bob, "My first post", "Hello world").save();

        // Post a first comment
        bobPost.addComment("Jeff", "Nice post");
        bobPost.addComment("Tom", "I knew that !");

        // Count things
        assertEquals(1, UserT.count());
        assertEquals(1, Post.count());
        assertEquals(2, Comment.count()); // 2 when correct not 0
        assertEquals(2, bobPost.comments.size());

    }

Остальной код такой же, как показано в вашем вопросе.Тест проходит для меня.ПРИМЕЧАНИЕ: если вы запускаете его дважды подряд и не стираете БД между тестами, в утверждениях произойдет сбой.

В качестве альтернативы вы можете использовать эти изменения для Post:

public Post(UserT author, String title, String content) {
    this.author = author;
    this.title = title;
    this.content = content;
    this.postedAt = new Date();
    this.comments = new ArrayList<Comment>();
}

public Post addComment(String author, String content) {
    Comment newComment = new Comment(this, author, content).save();
    this.comments.add(newComment);
    return this.save();
}

Это будет работать без необходимости перечитывать из базы данных состояние, так как оно обновляется немедленно.Это также проходит тест.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...