最近打算用grails做点东西,有很多很好的特性,但是新东西就是不稳定啊,用的时候遇到不少诡异的问题,现在把问题记录下来,以备忘。
1. 在其它类中调用domain class,编译报不能resolve。
情况一:因为grails默认生成的domain class是包内可见的作用域,所以测试用例一定要在相同的包目录下,或者干脆都声明成为public。
情况二:包目录是对的,但是eclipse还报错。其实直接执行是对的,这是eclipse的bug,也是声明成public保存一下就行了,如果不想用public,再把声明删掉。
情况三:找到相应的目录结构,直接用eclipse建立了一个groovy的class,结果用test-app的时候提示没有该类。换成用命令建立test类就行了,看来grails工程对自己建立的类还有管理,可能就是为了让integration和unit要启动的环境不一样吧。官方解释就是单元测试就要运行的快,要不程序员就会不愿意去做这个事情。
(各种诡异bug的迷惑,研究了半天...)
2. 在写单元测试的时候,提示domain class没有save()方法,当然其他的domain方法也都不能用。
根据研究发现,原因是unit test启动时压根没启动Hibernate Plugin,估计其他的Plugins也都没启动。把这样的用例放到integration test下面就正常了。这可能是grails希望程序员能把这两种用例的作用清晰的分开吧。
3. 有关联关系的两个domain class,用save()方法时提示not-null property references a null or transient value
由于还不会用grails的debug,研究了半天。
ClassA: staitc belongsTo = [classB:ClassB]
ClassB: static contraints = {name(unique:true)}
由于写了一个unique:true,另外一个类就必须在contraints里面声明classB(nullable:true)
4. 如何使用debug调试
先grails install-plugin debug,然后你回发现在%GRAIL_HOME%/bin下面多了一个grails-debug的命令。
启动要调试的程序,比如grails-debug run-app。
程序开启了远程调试运行模式,开启了监听端口5005,用eclipse的远程调试连接上即可。(不会自己去查怎么做)
5. grails如何使用spring的IOC
配置信息写在resources.groovy或者resources.xml里面,其内部依赖注入的原理和spring一样,毕竟是调用spring框架。问题是如何取到在spring容器里面定义好的对象呢。比较有意思的是我真的没找到相应的方法,只是定义了一个与beanId同名的变量,就自动拿到对象了。
看来这是动态语言在搞的鬼,我的理解是当如果一个对象没有定义,它就会去spring容器里面找是否存在相同命名的变量,如果找到就自动依赖注入。如果定了对象类型,那么查找容器实例的时候还会验证是否是声明的那个类型,所以我觉得还是要使用显示的对象类型声明。
具体方式官方的解释是:Grails service classes support injection by type or name,and a bean class can be injected into a Grails controller by specifing a corresponding property name.
由于没有显示的声明注入到哪个类,所以命名一定要保持一致系统才能识别,这个和spring的自动加载方式是一样的。
6. 有些对象使用如validator{... -> ...}是什么意思
这个是groovy里面的语法,这个类型closure的一种。其实就是一个更简洁的方式定义一个类,具体参考http://groovy.codehaus.org/Closures
7. 什么情况enviroments对应什么的环境
执行grails run-app是development环境,
执行grails test-app是test环境,
执行grails prod run-app是production环境
8. 怎么打印日志
首先我承认这是一个非常2b的问题,但是却困扰我很久。
grials把log4j集成了,在任何类都可以直接写log.info之类的日志打印(至于为什么要分fine, finer, finest级别,可能是为了更详细的日志打印划分,我用debug级别已经足够了)。比较恶心的是eclipse的插件在有的类认识log,有的又不认识,不要管ide的报错,无视他就好了...
在测试类当中,如果遇到log.error,那么该项测试就fail了,也不再往后运行。但是该错误日志不在console显示,必须要test reports页面去看;其他级别的日志都能在console直接看到。(实这个设计的很合理,就是找不到相关的说明文档... 但请注意页面的滚动条,别被前面那个No signature of method: java.util.logging.Logger.error()的报错迷惑了,我就是受害者之一,天天晚上coding真是观察力下降严重)。
更多的东西,我单独写一篇好了。网上的办法试多了,自己都给绕进去了,做了很多测试才搞明白,费劲~!
9. 多个domain之间有复杂关联关系,怎么定义
基本的定义方法看帮助文档就行了,但是有个地方把我弄糊涂了。
one-to-many需要有static belongsTo=[publisher:Publisher]
many-to-many写的是static belongsTo=Author
如果一个类要两个约束都写上,怎么写?
做了写测试,其实两种方式是一样的,只是第一种相当与有个别名。那么就写成
static belongsTo=[publisher:Publisher, author:Author] 或者 static belongsTo=[Publisher, Author]
本文转自passover 51CTO博客,原文链接:http://blog.51cto.com/passover/425474,如需转载请自行联系原作者