Yabe中的NPE空指针异常

时间:2011-07-27 23:07:20

标签: java nullpointerexception playframework

我正在完成Yabe教程并在测试中遇到一些Null指针异常使用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());
}

这里是接近结尾的带有addComment方法的Post类。

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 个答案:

答案 0 :(得分:4)

我没有看到Post.comments在任何地方被初始化,但addComment()尝试用this.comments.add(...)取消引用它。

答案 1 :(得分:1)

答案各种各样,Yabe的完整正确版本包含在安装中 play_installation] samples-and-tests
如果你感到困惑,你可以比较和对比,看看你哪里出错了。

答案 2 :(得分:0)

我知道您通过提供通用提示来回答您自己,并在您的Play中查找示例代码!安装,但对于其他人来到这里可能会更有帮助:

@RyanStewart是对的,你需要初始化“Post.comments”。

它实际上在教程中编写,但它很容易错过它(我自己做了,我已经习惯了Django自己做的一切,以实现我可能必须自己初始化!)

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

答案 3 :(得分:-1)

编辑:我在家做了测试,原始答案和新答案之间略有不同:

  • 我没有注意到代码中的List,因为它太靠近构造函数了。我的坏!
  • 我忘了添加刷新方法以从实体上的数据库中检索新状态

修改方法:

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

    }

其余代码与您在问题中显示的相同。测试通过我。注意:如果你连续两次运行它并且你没有在测试之间擦除数据库,它将在断言中失败。

或者,您可以将这些更改用于发布:

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

这将无需重新从数据库重新读取状态,因为它会立即更新。这也通过了测试。