【问题标题】:inserts in database failing from grails service从 Grails 服务中插入数据库失败
【发布时间】:2012-02-08 06:10:24
【问题描述】:

我使用 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 的相同数据源时..一个接一个..它可以工作..所以方言工作正常。但是这个批量更新服务不起作用。

【问题讨论】:

  • 与您的问题无关 - 如果这是 grails-app/services 中的服务,您正在做太多工作才能获得 dataSource bean。您可以跳过 applicationholder 位,只使用 def dataSource,因为您可以使用 def <beanname> 将任何 Spring bean 注入服务(或其他工件)。
  • 嗨...是的,我阅读了您的文章...但是在我的控制器中,我正在调用 new service() ...在更改它时总体会发生什么变化?以及与问题相关的内容...我是否必须坚持使用域类仅用于使用休眠的自动 id 生成,如果是,我如何以最快的方式在 globalusers 域类中设置 72 个字段..如果没有,我该怎么做我的代码适用于所有数据库?

标签: hibernate grails groovy datasource


【解决方案1】:

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

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

【讨论】:

    【解决方案2】:

    我不知道 grails,但在我看来

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

    【讨论】:

    • 谢谢...所以换句话说,对于自动 ID 生成,我必须使用与 GLOBALUSERS 关联的域/实体类,并且没有其他方法可以使用普通插入来解决这个问题???
    • 这一切都取决于ID生成策略。由于您使用的是 Oracle,我猜您正在为您的 ID 使用序列。您可以自己查询序列 nextval,甚至可以显式调用 Hibernate 生成器。但是,如果您的计划是使用原生 SQL 查询,我不明白您为什么要使用 Hibernate。
    • 对于从 UI 创建用户,我们确实使用了 USERS 域类及其工作正常,我们在整个应用程序中使用 Hibernate 来实现与数据库相关的所有功能,只是这是一个外部 userimportservice,它可以导入 50000 个用户因此,为了简单和速度,它是使用本机 sql 开发的。 users 表有 75 列,为所有要导入的用户设置每个属性会使其变慢,我想知道如何显式调用休眠生成器,最后脚本应该适用于 mysql 和 oracle,所以使用 nextval () 会使其成为特定于 oracle 的吗?
    • 你有没有测量过它太慢了?如果你按照docs.jboss.org/hibernate/core/3.6/reference/en-US/html_single/… 所说的话,我敢肯定它不会比使用 SQL 插入慢很多。
    • ok 听起来不错,但这是一个重大变化。我想在此之前尝试显式调用休眠生成器。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-08-15
    • 1970-01-01
    • 2021-04-09
    • 2018-01-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多