当前位置: 首页 > 知识库问答 >
问题:

org.hibernate。AssertionFailure:[…]项中的空id(发生异常后不要刷新会话)

太叔英锐
2023-03-14

我设置了一个非常基本的Grails 3 web应用程序,使用jdbc连接到PostgreSQL数据库。下面您可以找到< code>Cluster域类和专用服务的代码。

碰巧用同一个< code>slug参数调用了< code>createCluster方法两次:

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]

我以为违反一约束会被.validate()方法拦截,但显然我错了。好吧,所以我添加了一个try/catch,但它基本上没有效果,异常没有被包装,我基本上得到了一个500的内部错误。

我的问题是2:

  1. 为什么这个例外没有像我预期的那样被抓住?
  2. 空 id / 在发生异常错误后不刷新会话的真正含义是什么?我没有显式刷新会话,当然新记录的id为空...

在检查了几个指出相同问题的线程后,其中2个线程暗示要将Hibernate正在使用的数据源的JTA设置为TRUE。说我不知道该怎么做,据我所知,JTA更倾向于管理多个数据库之间的多个事务,所以我肯定会说这不是我的情况......我说的对吗?

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
    }
}

应用yml(数据库配置)

dataSource:
    pooled: true
    driverClassName: 'org.postgresql.Driver'
    dialect: 'org.hibernate.dialect.PostgreSQLDialect'
    username: 'postgres'
    password: 'postgres'

environments:
    development:
        dataSource:
            dbCreate: create
            url: jdbc:postgresql://localhost:5432/myapp

共有1个答案

尹弘壮
2023-03-14

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

compile "org.grails.plugins:hibernate"

compile "org.grails.plugins:hibernate4"

使问题消失,. valize()按预期返回false并且没有抛出错误。

然而,我找不到任何关于Grails 3和Hibernate 3不兼容的注释,最好能找到一个:P

 类似资料: