问题:错误500:内部服务器错误
URI: /listing/save
Class: org.hibernate.AssertionFailure
Message: getGeneratedKeys() support is not enabled
配置
可用的控制器:
操作系统: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
重现问题:
编辑: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:\开发\电话簿> grails create-domain-class phonebook.listing 编辑:的grails-app \域\电话簿\ 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异常
研究和故障排除活动:
我试图通过grails-app \ conf \ application.yml中的以下部分解决问题:
hibernate:
jdbc:
use_get_generated_keys: true
cache:
queries: false
...
我怀疑该解决方案涉及grails-app \ conf \ application.yml中的特定设置,但尚未发现配置设置的正确组合。
答案 0 :(得分:0)
您也可以尝试从身份序列生成器(我相信Oracle方言的默认值)切换到seq-hilo:
在Grails 2.x中,您可以通过以下方式完成:
grails.gorm.default.mapping = {
id generator: 'seqhilo', params: [max_lo: 1000]
}
我认为它在application.yml文件中的3.x中的工作方式类似。这应该可以防止hibernate甚至需要使用getGeneratedKeys()方法,因为它会将id从它自己的内存池中绑定到insert中,而不是在insert语句中执行seq.nextval。
答案 1 :(得分:0)
好的,当查看application.yml配置文件中的哪个位置放置第一个答案的建议时,我发现我使用的hibernate.jdbc.use_get_generated_keys = true设置实际上是在grails块下。虽然以前从未使用过yml文件,但我并不知道缩进和块形成配置设置的潜在重要性。当我第一次对文件进行编辑时,我查看是否已经有一个休眠部分,我将此设置放在该块中,从而导致设置为grails.hibernate.jdbc.use_get_generated_keys。我在hibernate的root(无缩进)下创建了设置并进行了测试。结果是成功完成了行动。
我希望这篇文章能够帮助其他新用户使用这个配置文件,这个文件在以groovy为中心的框架中似乎不合适。我将查看创建新的grails应用程序是否有一个选项来使用groovy配置文件而不是yml文件。
答案 2 :(得分:0)
通过添加
修复了Oracle 12的这个问题 jdbc:
use_get_generated_keys: true
并将oracle jdbc驱动程序升级到ojdbc7 12.1.0.2(12.1.0.1不起作用)
答案 3 :(得分:0)
对于Grails 3,Hibernte 4,Oracle 10c +以下配置可用。
在build.gradle中配置了Hibernate 4,默认情况下是Grails 3.1.6的
在application.yml
中hibernate:
jdbc:
use_get_generated_keys: true
id:
new_generator_mappings: true
然后在域对象中配置id字段以使用Oracle序列作为密钥,如下所示:
class Person {
String name
static constraints = {
id generator:'sequence-identity', params:[sequence:'person_key_seq']
}
}
Oracle最近才推出自动生成的ID字段,我认为12.但Hibernate 4只有org.hibernate.dialect.Oracle10gDialect,所以你不能使用新的Oracle自动密钥功能而不使用Hibernate 5如果您可以使用Hibernate 5,那么Oracle12cDialect可用,这将允许Hibernate和Oracle在直接处理数据库时在GORM和SQL中为您生成密钥生成。但是,从Grails 3.1.6开始,在某些服务器上成功部署Hibernate 5存在问题,因此请注意,如果您尝试切换。