插入数据库失败的grails服务

时间:2012-01-11 21:25:36

标签: hibernate grails groovy datasource

我使用oracle11g作为数据库,并尝试从我的grails服务类插入globalusers表。 我正在检索grails服务中的数据源,如下所示:

import org.codehaus.groovy.grails.commons.ApplicationHolder as AH 
class UserImportService {
 def dataSource = AH.application.mainContext.dataSource
 def sql = new Sql(dataSource) ;
 String insertQuery="insert into GLOBALUSERS (..) values (..)
                try{
                    sql.execute(insertQuery)
                }
                catch(Exception e){

                    println "Failed to insert : " +insertQuery
                    println "Exception is:" + e;

                }
}

当我从前端运行服务时,我得到sql异常说

Exception is:java.sql.SQLIntegrityConstraintViolationException: ORA-01400: cannot insert NULL into ("GRA"."GLOBALUSERS"."ID")

由于我使用的数据源与我的自定义方言处理ID生成和自动增量,因此应由grail / hibernate处理。

当从其他UI使用相同的数据源时......一个接一个..它的工作原理..所以方言工作正常。但是这种批量更新服务无效。

2 个答案:

答案 0 :(得分:2)

我不知道grails,但在我看来

  • 您的代码根本不使用Hibernate。它直接执行SQL
  • 即使它使用了Hibernate,在Hibernate中使用SQL查询也会完全绕过ID生成。对于自动ID生成,您必须实例化并持久保存实体。

答案 1 :(得分:1)

dataSource bean上执行直接Sql将绕过Hibernate的id生成方法,据我所知,它在适当的Oracle序列上执行nextval()。所以你的选择是:

  • 使用Grails / GORM创建对象,填充和.save()
  • 自己查询序列,这将涉及对序列执行nextval(),但它会使您的Sql特定于Oracle
  • 向数据库添加Oracle触发器,该数据库测试是否设置了主键,如果不是,则执行nextval()序列查询并将其添加到新数据库行。这将使您的直接Sql与MySql自动增量和Oracle序列保持兼容。