hibernate - org.hibernate.AssertionFailure:[…]条目中的id为null(发生异常后不要刷新Session)

标签 hibernate postgresql grails gorm grails-domain-class

我建立了一个非常基本的Grails 3网络应用程序,它使用jdbc连接到PostgreSQL数据库。您可以在下面找到Cluster域类和专用服务的代码。

碰巧用相同的createCluster参数两次调用了slug方法:

clusterService.createCluster('Cluster 1', 'cl01')
clusterService.createCluster('Cluster 2', 'cl01')

导致以下异常
ERROR org.hibernate.engine.jdbc.spi.SqlExceptionHelper - ERROR: duplicate key value violates unique constraint "uk_9ig73x9wropf95ogrffcvyahk"
  Detail: Key (slug)=(cl01) already exists.
[...]
null id in myPackage.Cluster entry (don't flush the Session after an exception occurs). Stacktrace follows:
    org.hibernate.AssertionFailure: null id in myPackage.Cluster entry (don't flush the Session after an exception occurs)
    at grails.transaction.GrailsTransactionTemplate.execute(GrailsTransactionTemplate.groovy:93) ~[grails-core-3.1.1.jar:3.1.1]
    at com.usablenet.utest.AdminController.clusters(AdminController.groovy:28) ~[main/:na]
    at grails.plugin.springsecurity.web.filter.GrailsAnonymousAuthenticationFilter.doFilter(GrailsAnonymousAuthenticationFilter.groovy:53) ~[spring-security-core-3.0.3.jar:na]
    at grails.plugin.springsecurity.web.authentication.logout.MutableLogoutFilter.doFilter(MutableLogoutFilter.groovy:62) ~[spring-security-core-3.0.3.jar:na]
    at grails.plugin.springsecurity.web.SecurityRequestHolderFilter.doFilter(SecurityRequestHolderFilter.groovy:58) ~[spring-security-core-3.0.3.jar:na]
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) ~[na:1.8.0_60-ea]
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) ~[na:1.8.0_60-ea]
    at java.lang.Thread.run(Thread.java:745) [na:1.8.0_60-ea]

I assumed that the violation of the unique constraint would had been intercepted by the .validate() method, but apparently I was wrong. Ok, so I added a try/catch but it basically has no effect, the exception is not wrapped and I basically get a 500 Internal Error.

My questions are 2:

  1. why isn't this exception catched as i would expect?
  2. what does null id / don't flush the Session after an exception occurs error really mean? I'm not explicitly flushing the session, and of course the new record's id is null...

After checking a few threads pointing out the same issue, 2 of them hinted to set JTA to TRUE for the data source that Hibernate is using. Said that I have no clue how to do that, as far as I understood JTA is more oriented to manage multiple transactions among multiple databases, so I'd definitely say it's not my case... Am I right?

Cluster.groovy (domain class)

class Cluster {

    String name
    String slug

    static constraints = {
        name    blank: false, unique: true
        slug    blank: false, unique: true
    }

}

ClusterService.groovy
@Transactional
class ClusterService {

    public Cluster createCluster(String name, String slug, boolean flush = false) {
        Cluster cluster = new Cluster(name: name, slug: slug)
        try {
            if(cluster.validate())
                cluster.save(flush: flush)
        } catch(Exception e) {
            e.printStackTrace()
        }
        return cluster
    }
}

application.yml (数据库配置)

数据源:
合并:true
driverClassName:“org.postgresql.Driver”
方言:'org.hibernate.dialect.PostgreSQLDialect'
用户名:“postgres”
密码:“postgres”

环境:
发展:
数据源:
dbCreate:创建
网址:jdbc:postgresql:// localhost:5432 / myapp

最佳答案

从头开始构建演示时,我发现问题不是我的代码,而是Grails应用程序的配置(build.gradle),因为它只是更改依赖项

compile "org.grails.plugins:hibernate"


compile "org.grails.plugins:hibernate4"

使问题消失了,.validate()按预期返回了false,并且没有引发错误。

但是我找不到关于Grails 3之间不兼容的任何注释
和Hibernate 3,很高兴找到一个:P

关于hibernate - org.hibernate.AssertionFailure:[…]条目中的id为null(发生异常后不要刷新Session),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35776686/

相关文章:

java - 如何更新一对一关系表?

java - Hibernate:如何将子类链接到其父类(super class)?

sql - postgresql string agg 数字/整数输出结果错误

grails - 如何使用 Grails 3.3.x 在 groovy/src 类中模拟服务

java - Jpa 存储库特殊词,如 "and' 、 "or"不起作用

java - Hibernate - @OneToMany 实体的持久集合

postgresql - 等待服务数据库在Docker中运行的其他服务之前运行

postgresql - Docker PostgreSQL:初始化脚本

grails - 构建Grails应用程序时出错

grails - 如果没有渲染,remoteFunction将无法工作