为啥grails在第一次访问hasMany关系时抛出空指针异常?
Posted
技术标签:
【中文标题】为啥grails在第一次访问hasMany关系时抛出空指针异常?【英文标题】:Why grails throwing null pointer exception while accessing hasMany relationship first time?为什么grails在第一次访问hasMany关系时抛出空指针异常? 【发布时间】:2011-10-19 21:06:58 【问题描述】:我有一个奇怪的问题。
我有两个域类 User
和 Post
字段:
class User
String name
static hasMany = [posts: Post]
static constraints =
和
class Post
String content
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 "Posts count: " + user.posts.size()
render "post count: " + user.posts.size()
第一次访问 url http://localhost:8080/test/user/addUser
时,会抛出空指针异常,但之后就可以正常工作了。
这是我得到的例外
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)
第二次,它像魅力一样打印和渲染
Posts count: 0
在用户域类中,因为posts
、posts
的hasMany
关系是Post
对象的列表,那么在获取空列表的大小时不应该出现空指针异常,而是应该为零。
任何帮助表示赞赏
【问题讨论】:
【参考方案1】:当你像这样映射一个集合时,hasMany
声明会向你的类添加一个类型为 Set
且具有指定名称(在本例中为 posts
)的字段。但是它不会初始化集合,所以它最初是空的。当您调用 addToPosts
时,它会检查它是否为 null,并在必要时创建一个新的空 Set,并将 Post 添加到集合中。但是如果你不调用addToPosts
或者显式初始化set,它就会为null。
当您从数据库加载User
时,Hibernate 将填充所有字段,并且集合包含在其中。它创建一个新的空集(一个修改感知PersistentSet
),如果有任何实例,它就会向它添加实例。调用save()
不会从数据库中重新加载实例,所以空集仍然是空的。
要让类在新类和持久类时表现相同,您可以向类中添加一个字段,就像 Rob 在他的回答中显示的那样,初始化为一个空集 (Set posts = []
)
【讨论】:
【参考方案2】:您可以通过在映射旁边显式声明您的集合属性(带有值)来防止这种情况:
class User
String name
Set posts = []
static hasMany = [posts: Post]
您可以定义您需要的集合类型。默认为Set
,但如果需要维护秩序,可以考虑List
或SortedSet
。
【讨论】:
是的,默认设置是 Set,但我使用 List,因为我将“posts”解释为具有排序的东西。不管怎样,SortedSet 可能更合适。以上是关于为啥grails在第一次访问hasMany关系时抛出空指针异常?的主要内容,如果未能解决你的问题,请参考以下文章
grails:脚手架为具有 hasMany 关系的域创建视图
Grails - 简单的 hasMany 问题 - 在 create.gsp 中使用 CheckBoxes 而不是 HTML Select