问题:错误 500:内部服务器错误
URI: /listing/save
Class: org.hibernate.AssertionFailure
Message: getGeneratedKeys() support is not enabled
配置
- 环境:发展
- 应用简介:网络
- 应用版本:0.1
- Grails 版本:3.0.1
- Groovy 版本:2.4.3
- JVM 版本:1.8.0_45(64 位)
- 重新加载活动:true
可用控制器:
- 电话簿.ListingController
操作系统:Windows 7 数据库:Oracle 11g R2 企业版(11.2.0.4 64 位)
调试输出包含:
Grails application running at http://localhost:8080
ERROR org.hibernate.AssertionFailure - HHH000099: an assertion failure occured (this may indicate a bug in Hibernate, but is more likely due to unsafe use of the session): org.hibernate.AssertionFailure: getGeneratedKeys() support is not enabled
ERROR org.grails.web.errors.GrailsExceptionResolver - AssertionFailure occurred when processing request: [POST] /listing/save - parameters:
name: Scott
phone: 555-1212
create: Create
getGeneratedKeys() support is not enabled. Stacktrace follows:
org.hibernate.AssertionFailure: getGeneratedKeys() support is not enabled
at phonebook.ListingController.$tt__save(ListingController.groovy:38) ~[main/:na]
at grails.transaction.GrailsTransactionTemplate$2.doInTransaction(GrailsTransactionTemplate.groovy:93) ~[grails-core-3.0.1.jar:3.0.1]
at grails.transaction.GrailsTransactionTemplate.execute(GrailsTransactionTemplate.groovy:90) ~[grails-core-3.0.1.jar:3.0.1]
at grails.transaction.GrailsTransactionTemplate$2.doInTransaction(GrailsTransactionTemplate.groovy:93) ~[grails-core-3.0.1.jar:3.0.1]
at grails.transaction.GrailsTransactionTemplate.execute(GrailsTransactionTemplate.groovy:90) ~[grails-core-3.0.1.jar:3.0.1]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) ~[na:1.8.0_45]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) ~[na:1.8.0_45]
at java.lang.Thread.run(Thread.java:745) [na:1.8.0_45]
File: grails-app\controllers\phonebook\ListingController
Line: 38
Content: listing.save flush:true
重现问题:
- C:\Dev> grails 创建应用电话簿
- C:\Dev> cd 电话簿
编辑:build.gradle
dependencies {
...
runtime "com.oracle:jdbc-lib-ojdbc6:11.2.0.4"
...
}
注意:Oracle 客户端 ojdbc6.jar 在上面指定的坐标处添加到本地 Maven 存储库。
编辑:grails-app\conf\application.yml
...
dataSource:
pooled: true
jmxExport: true
driverClassName: oracle.jdbc.OracleDriver
username: scott
password: tiger
environments:
development:
dataSource:
dbCreate: update
url: jdbc:oracle:thin:@localhost:1521/sbx1
...
C:\Dev\phonebook> grails create-domain-class phonebook.listing 编辑:grails-app\domain\phonebook\Listing.groovy
package phonebook
class Listing {
String name
String phone
static constraints = {
name maxSize: 50
phone maxSize: 14
}
}
C:\Dev\phonebook> grails generate-all phonebook.listing
C:\Dev\phonebook> grails run-app
下面确认应用程序连接数据库并成功创建表:
SQL> describe listing
Name Null? Type
----------------------------------------- -------- ----------------------------
ID NOT NULL NUMBER(19)
VERSION NOT NULL NUMBER(19)
NAME NOT NULL VARCHAR2(50 CHAR)
PHONE NOT NULL VARCHAR2(14 CHAR)
架构中还创建了两个序列:
HIBERNATE_SEQUENCE
LISTING_SEQ
注意:这些肯定是由于我多次尝试修改域类中的映射属性以生成 ID 的结果而创建的。
嵌入式 Tomcat 服务器在http://localhost:8080/上运行后的操作 Internet Explorer:http://localhost:8080/ 单击链接:可用控制器 > phonebook.ListingController 单击:新建列表完成表单并单击:创建结果:上述 Grails 异常
研究和故障排除活动:
- 不存在的问题只是 Oracle 到 H2/HSQL 文件/内存数据库的变化
- 发现 hibernate.jdbc.use_get_generated_keys 设置,但通过在 application.yml 配置文件中设置 true 未能成功解决问题
- 在 grails-app/conf/DataSource.groovy 中找到了对设置的多个引用,但这是使用 application.yml 的 Grails 3
- 尝试在域类中使用生成器映射 ID 列的多个属性
- 在涵盖此主题的 Grails 3 文档中几乎没有发现任何信息
- Hibernate 文档涵盖了配置设置和 ID 生成器,但不提供该信息的 Grails / Groovy 应用程序
- Hibernate 文档指出,不显式设置 hibernate.jdbc.use_get_generated_keys 会导致它由 jdbc 连接数据库元数据自动设置
我试图通过 grails-app\conf\application.yml 中的以下部分来解决问题:
hibernate:
jdbc:
use_get_generated_keys: true
cache:
queries: false
...
我怀疑该解决方案涉及 grails-app\conf\application.yml 中的特定设置,但尚未发现配置设置的正确组合。