我有以下代码,它将新对象添加到数据库中。首先,它从DB获取另一个对象并添加到最终对象。
我的代码几行
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(未知 来源)at xxx.AuditLogService.getCurrentUser(AuditLogService.groovy:127)at xxx.AuditLogService $ getCurrentUser.callStatic(未知来源)at xxx.AuditLogService $ _closure2.doCall(AuditLogService.groovy:58)at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) 在 sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) 在java.lang.reflect.Method.invoke(Method.java:597)at org.springsource.loaded.ri.ReflectiveInterceptor.jlrMethodInvoke(ReflectiveInterceptor.java:1243) 在 org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:90) 2013-08-02 09:39:11,110 ERROR ErrorLogger - Job(DEFAULT.1扔了一个 例外。 org.quartz.SchedulerException:Job扔了一个未处理的 例外。在org.quartz.core.JobRunShell.run(JobRunShell.java:224) 在 org.quartz.simpl.SimpleThreadPool $ WorkerThread.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(未知 来源)at xxx.AuditLogService.getCurrentUser(AuditLogService.groovy:127)at xxx.AuditLogService $ getCurrentUser.callStatic(未知来源)at xxx.AuditLogService $ _closure2.doCall(AuditLogService.groovy:58)at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) 在 sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) 在java.lang.reflect.Method.invoke(Method.java:597)at org.springsource.loaded.ri.ReflectiveInterceptor.jlrMethodInvoke(ReflectiveInterceptor.java:1243) 在 org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:90)
答案 0 :(得分: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)
}
答案 1 :(得分:0)
看看AuditLogService。您似乎正在对域类(或Hibernate)实现某种审计或安全性,这需要安全上下文,而您在一个外部调用此代码。
另外,出于好奇,为什么要在c上调用.merge()?