1

我有以下代码将新对象添加到数据库。首先,它从数据库中获取另一个对象并添加到最终对象中。

我的几行代码

            ClassC c = ClassC.findByName(cName)

            ClassD d = new ClassD(
                    name: "WHATEVER",
                    classC: c
            )

            print "AAA\n"

            ClassC.withTransaction {
                c = c.merge()
                // c.save(failOnError: true, flush: true)
            }

            print "BBB\n"

            // ClassD.withTransaction {
            //     d = d.merge()
            // }
            // print "CCC\n"

            ClassD.withTransaction {
                d.save(failOnError: true, flush: true)
            }

            print "DDD\n"

我收到以下错误:

AAA
BBB

2013-07-31 13:57:14,279 ERROR JobRunShell - Job DEFAULT.1 threw an unhandled Exception: 
 org.springframework.dao.DuplicateKeyException: a different object with the same identifier value was already associated with the session: [xxx.ClassD#15]; nested exception is org.hibernate.NonUniqueObjectException: a different object with the same identifier value was already associated with the session: [xxx.ClassD#15]

你可以帮帮我吗?

谢谢


ClassC.withTransaction {
    ClassC c = ClassC.findByName(cName)

    // find the record with name: "WHATEVER" or create a new one if there is none
    ClassD d = ClassD.findOrCreateWhere(name: "WHATEVER")

    c = c.merge()
    c.addToClassesD(d) // static hasMany = [classesD: ClassD] <-- in ClassC domain
    c.save(failOnError: true, flush: true)
}

错误来自行

c.addToClassesD(d)

java.lang.IllegalStateException:未找到线程绑定请求:您是指实际 Web 请求之外的请求属性,还是在原始接收线程之外处理请求?如果您实际上是在 Web 请求中操作并且仍然收到此消息,则您的代码可能在 DispatcherServlet/DispatcherPortlet 之外运行:在这种情况下,请使用 RequestContextListener 或 RequestContextFilter 来公开当前请求。在 org.springframework.web.context.request.RequestContextHolder.currentRequestAttributes(RequestContextHolder.java:131) 在 org.springframework.web.context.request.RequestContextHolder$currentRequestAttributes.call(Unknown Source) 在 xxx.AuditLogService.getCurrentUser(AuditLogService. groovy:127) 在 xxx.AuditLogService$getCurrentUser。run(SimpleThreadPool.java:557) 原因:java.lang.IllegalStateException:未找到线程绑定请求:您是指实际 Web 请求之外的请求属性,还是在原始接收线程之外处理请求?如果您实际上是在 Web 请求中操作并且仍然收到此消息,则您的代码可能在 DispatcherServlet/DispatcherPortlet 之外运行:在这种情况下,请使用 RequestContextListener 或 RequestContextFilter 来公开当前请求。在 org.springframework.web.context.request.RequestContextHolder.currentRequestAttributes(RequestContextHolder.java:131) 在 org.springframework.web.context.request.RequestContextHolder$currentRequestAttributes.call(Unknown Source) 在 xxx.AuditLogService.getCurrentUser(AuditLogService. groovy:127) 在 xxx。

4

2 回答 2

2

您可能应该只在一个事务中完成所有操作。

至于您遇到的错误,我假设您已经unique设置了名称 - 当已经有一个名称为“WHATEVER”的记录时,您会收到该错误。

你可能想做这样的事情:

ClassC.withTransaction {
    ClassC c = ClassC.findByName(cName)

    // find the record with name: "WHATEVER" or create a new one if there is none
    ClassD d = ClassD.findOrCreateWhere(name: "WHATEVER")

    c = c.merge()
    d.classC = c
    d.save(failOnError: true, flush: true)
}
于 2013-07-31T12:13:08.527 回答
0

看看 AuditLogService。似乎您正在对域类(或 Hibernate)实施某种审计或安全性,这需要一个安全上下文,而您在外部调用此代码。

另外,出于好奇,您为什么要在 c 上调用 .merge() ?

于 2013-08-02T07:50:39.873 回答