为什么Grails在第一次访问hasMany关系时抛出空指针异常? [英] Why grails throwing null pointer exception while accessing hasMany relationship first time?

查看:130
本文介绍了为什么Grails在第一次访问hasMany关系时抛出空指针异常?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个奇怪的问题。

我有两个域类 User Post 字段:

  class User {
字符串名称
static hasMany = [posts:Post]
static constraints = {
}

  class Post {
字符串内容
long date = System.getTimeInMillis()
static constraints = {}

static belongsTo = [user:User]
static mapping = {
version:'false'
}
}



和控制器代码是:

  class UserController { 
def addUser = {
def user
if(User.count()== 0){
user = new User()
user.name =Manish Zedwal
user.save(flush:true)
} else {
user = User.get(1)
}
println帖子数:+ user .posts.size()
renderpost count:+ user.posts.size()


$ / code>

第一次访问url http:// localhost:8080 / test / user / addUser ,它会抛出空指针异常,但是在正常工作之后。

这是我得到的异常

  2011-08-04 15:41:25,847 [http-8080-1] ERROR errors.GrailsExceptionResolver  - 处理请求时发生异常:[ GET] / test / user / addUser 
Stacktrace如下:
java.lang.NullPointerException:无法在null对象上调用方法大小()
在test.UserController $ _closure2.doCall(UserController.groovy :18)
at test.UserController $ _closure2.doCall(UserController.groovy)
at java.lang.Thread.run(Thread.java:636)



第二次打印并呈现精美的魅力

  b 




$ b

在用户域类中, hasMany 关系为文章文章 Post 对象的列表,那么在获得空列表大小时不应该有空指针异常,而应该是零。 / p>

任何帮助表示赞赏

解决方案

hasMany 声明会添加一个类型为 Set 的字段,并指定名称(在本例中为 posts )给你的班级。它不初始化集合,所以它最初是空的。当您调用 addToPosts 时,它会检查它是否为空,并在必要时创建一个新的空集,并将该Post添加到集合中。但是,如果您不调用 addToPosts 或显式初始化该集合,它将为空。



来自数据库的 User ,Hibernate将填充所有字段,并且集合包含在其中。它创建一个新的Set(一个修改感知的 PersistentSet ),它是空的,如果有的话添加实例。调用 save()不会从数据库重新加载实例,所以null集合仍然为空。



<为了让这个类在新的和持久的时候表现出相同的行为方式,你可以在类中添加一个字段像Rob在他的回答中显示的那样,初始化为一个空集( Set posts = [ ]


I have a strange problem.
I have two domain classes User and Post with fields:

class User {
  String name
  static hasMany = [posts: Post]
  static constraints = { }
}

and

class Post {
  String content
  long date = System.getTimeInMillis()
  static constraints = { }

  static belongsTo = [user: User]
  static mapping = {
    version: 'false'
  }
}

and controller code is:

class UserController {
  def addUser = {
    def user
    if (User.count() == 0) {
      user = new User()
      user.name = "Manish Zedwal"
      user.save(flush: true)
    } else {
      user = User.get(1)
    }
    println "Posts count: " + user.posts.size()
    render "post count: " + user.posts.size()
 }
}

For the first time while accessing url http://localhost:8080/test/user/addUser, it throws null pointer exception, but after this works fine.
This is the exception I am getting

2011-08-04 15:41:25,847 [http-8080-1] ERROR errors.GrailsExceptionResolver  - Exception occurred when processing request: [GET] /test/user/addUser
Stacktrace follows:
java.lang.NullPointerException: Cannot invoke method size() on null object
        at test.UserController$_closure2.doCall(UserController.groovy:18)
        at test.UserController$_closure2.doCall(UserController.groovy)
        at java.lang.Thread.run(Thread.java:636)

and for second time, it prints and renders fine like charm

Posts count: 0

In user domain class, coz of hasMany relationship for posts, posts is a list of Post objects then there shouldn't be null pointer exception on getting the size of empty list, rather it should be zero.

Any help appreciated

解决方案

When you map a collection like that, the hasMany declaration adds a field of type Set with the specified name (in this case posts) to your class. It doesn't initialize the set though, so it's initially null. When you call addToPosts it checks if it's null and creates a new empty Set if necessary, and adds the Post to the collection. But if you don't call addToPosts or explicitly initialize the set, it will be null.

When you load a User from the database, Hibernate will populate all the fields, and the collection is included in that. It creates a new Set (a modification-aware PersistentSet) that's empty, and adds instances to it if there are any. Calling save() doesn't reload the instance from the database though, so the null set will still be null.

To get the class to behave the same way when it's new and when it's persistent, you can add a field to your class Like Rob showed in his answer, initialized to an empty set (Set posts = [])

这篇关于为什么Grails在第一次访问hasMany关系时抛出空指针异常?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆