Grails开发项目中的错误及解决

阅读更多
Q: 如果有多个hasMany映射, 提示错误:
A: 需要定义在一个语句里: static hasMany = [activites:Activity,linkmen:Linkman];


--------------------------------------------------------------------------------

Q: 如果某个数据库中表没有建立起来:
A1: 一般是domain类的属性定义错误, 定义重复, 或者是属性名和Oracle的关键字重复. 比如title, user就不能作为属性名.
A2: 由于数据库的dbcreate选项用的是update, 所以有时候添加新表的时候建立不了新表. 或有些表的字段无法自动添加, 运行服务器的时候如果访问这样的表会报sql无法执行的错误, 此时需要吧config.groovy里的log4j的hibernate="off"改为hibernate="on", 这时hibernate的详细错误信息会显示在控制台上. 根据提示, 按照映射规则手工加入相应表或字段即可.


--------------------------------------------------------------------------------

Q: 在增加Acegi0.5插件后, 提示java.lang.UnsupportedClassVersionError: Bad version number in .class file :
A: 编译需要jdk1.6, 所以把构建路径的jdk更改成1.6.


--------------------------------------------------------------------------------

Q: navtive2ascii错误解决办法
A: 右键项目,点击属性 找到 Java构建路径 ,点击库--添加外部jAR 选择JDK下lib文件夹里的 tools.jar确定保存


--------------------------------------------------------------------------------

Q: Hibernate自动映射读取其他用户表的解决办法
A: 用dba进入数据库, 把crmdev的dba权限去掉, 只保留connect和resource权限.


--------------------------------------------------------------------------------

Q: 默认用户注册页面注册提示"没有默认的角色"
A: 在角色管理里建立角色user, 进入SecurityConfig.groovy, 添加defaultRole="user" .


--------------------------------------------------------------------------------

Q: 为什么在国际化资源文件message.properties里录入的中文, 编译后变成乱码?
A: 首先在属性里确定此文件的编码是utf-8, 如果不是请改成utf-8, 然后用Eclipse编辑器打开此文件, 用Properties界面添加/编辑此文件, 而不要用Source界面编辑. Source界面编辑后的文件经过native2ascii转换后再用Properties界面看就是乱码了.


--------------------------------------------------------------------------------

Q: 为什么页面上显示乱码?
A1: Eclipse所有自动生成的GSP文件默认编码都是ISO-8859-1, 在编辑前一定要手动改成UTF-8编码.


--------------------------------------------------------------------------------

Q: 为什么GSP页面的按钮国际化后不好使了,提示404错误?
A: 因为按钮如果不指定action, 默认的提交action和value相同, 但是因为value改成了中文, 所以action找不到了. 解决方法是在actionSubmit里显式指定action, 比如action="edit".


--------------------------------------------------------------------------------

Q: 为什么建立的角色在用户编辑的时候选不了?
A: 在保存用户的时候要判断角色的名称里包含"ROLE", 所以建立角色的时候请加"ROLE_"前缀.acegi插件自动生成的代码是这样判断的.


--------------------------------------------------------------------------------

Q: 怎么把数据库字段默认设置成可为空?
A: nullable可以使gorm建表时把字段设置成允许null.


--------------------------------------------------------------------------------

Q: 一个视图内不同Domain的字段重名, 导致绑定params出错怎么办?
A: 最好的做法是在设计Domain时在字段前面加Domain名字的前缀, 这样就可以保证字段不重名了.


--------------------------------------------------------------------------------

Q: 为什么GSP页面报空指针错误?
A: 这个原因可能很多, 但主要是因为某个属性写错了或没加"?"判断, 首先一定要看清是哪个页面, 因为有些保存页面后会调用Show.gsp. 这时不要一直在Create.Gsp找. 其次一般自动生成的代码是没有问题的, 主要看自己填写的代码. 比如添加了delete的message的参数, 如果从别的地方拷贝过来, 很可能参数没有改, 导致报错.


--------------------------------------------------------------------------------

Q: Null value was assigned to a property of primitive type setter 错误的解决方法?
A: 如果遇到这个错误: Null value was assigned to a property of primitive type setter ,hibernate int型数据无法读取 hiberante读int 整型数据出错 hiberante读数据库出错 解决方法: 把Domain里相应字段从int改为Integer.
.


--------------------------------------------------------------------------------

Q: 为什么Gsp页面Create画面在提交返回校验错误信息后, 关联表的信息都没有了?
A: 比如, 新建Linkman里有Customer的id, 但是在提交后返回"电话不能为空"后, Customer的信息就没有了. 这个产生的原因没有弄清楚提交循环. 在Controller 的Save闭包里, 如果提交有错误, 程序会执行else分支的内容, 返回提交页面, 此时若不把Customer信息读取并返回页面, 就会产生这个问题, 具体实例代码如下:

def save = {
        def customerInstance = Customer.get(params['customer.id'])
        def linkmanInstance = new Linkman(params)
        linkmanInstance.customer=customerInstance
        if(!linkmanInstance.hasErrors() && linkmanInstance.save()) {
            flash.message = "Linkman ${linkmanInstance.id} created"
            redirect(action:show,id:linkmanInstance.id)
        }
        else {
            render(view:'create',model:[linkmanInstance:linkmanInstance,customerInstance:customerInstance])
        }
    }

--------------------------------------------------------------------------------

Q: 有没有必须使用flush的时候?为什么我向数据库添加时提示:java.lang.NullPointerException: Cannot invoke method XXXMethod() on null object?
A: 这是一个问题, 前一个对象没有真正存到数据库里, 导致后面读取使用这个对象时出错. 所以在存这个对象时, 要flush一下, 即立即执行. 下面是一个例子:

其中的大写单词都是自定义常量

  if(!Role.findByAuthority(BASE_ADMIN_ROLE)){
             //这里是个需要立即提交的例子,如果这里不提交,下面建立用户时会找不到这个权限, 从而导致出错
             (new Role(authority:BASE_ADMIN_ROLE,description:BASE_ADMIN_ROLE)).save(flush:true)
         
         }
         if(!UserInfo.findByUsername(BASE_ADMIN)){
             def password = authenticateService.encodePassword(BASE_ADMIN)
             def baseAdmin = new UserInfo(username:BASE_ADMIN,userRealName:BASE_ADMIN,
                 passwd:password,enabled:true,email:"[email protected]").save()
             Role.findByAuthority(BASE_ADMIN_ROLE).addToPeople(baseAdmin);
         }

--------------------------------------------------------------------------------

Q: 为什么我在Service层里添加代码后在Controller里调用不好使?
A: Service层代码调用是需要先实例化的, 比如IndexController调用UserInfoService, 需要在IndexController里先声明def userInfoService. 这时Spring会自动装配. 然后在需要的地方调用userInfoService.getCurrentUser(session). 另外说明一点, session是需要传过去的. 不像Controller中可以直接调用.


--------------------------------------------------------------------------------

Q: 为什么我读的数据只显示1条? find和findAll的区别?
A: 这是因为列表是使用的是find, 它只会返回第一条, 但是findAll会返回所有记录.


--------------------------------------------------------------------------------

Q: org.hibernate.MappingException An association from the table ** refers to an unmapped class错误的解决方法?
A: 如果碰到类似org.hibernate.MappingException: An association from the table ** refers to an unmapped class 这样的错误,发现的产生这样错误的原因是: 把域文件另存为了UTF-8编码. 这样在重新启动服务器时就会报这个错误. 解决方法是: 把这个domain文件备份后删除, 重新用Grails生成一个domain文件, 然后把原来的class里的代码拷贝回来. 这样再启动服务器就正常了.

你可能感兴趣的:(Grails,项目管理,Hibernate,Groovy,Eclipse)