Grails、自定义验证器、Hibernate 断言错误
Grails, custom validator, Hibernate assertion error
我正尝试在我的域 class 中使用一项服务进行自定义验证。在其他领域 classes 这很有效,但在这里我收到一个 Hibernate 断言错误。
域 class 自定义验证:
end validator: { val, obj ->
if (obj.userWorkingTimeRegulationService.validateit() == false){
return ["error.workingregulation"]
}
我使用以下方式注入服务:
def userWorkingTimeRegulationService
该服务仅 returns 用于测试目的:
package usermanagement
import grails.transaction.Transactional
@Transactional
class UserWorkingTimeRegulationService {
def serviceMethod() {
}
def validateit(){
return true
}
}
堆栈跟踪:
| Error 2015-05-27 15:07:54,909 [localhost-startStop-1] ERROR 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: null id in usermanagement.UserWorkingTimeRegulation entry (don't flush the Session after an exception occurs)
| Error 2015-05-27 15:07:54,927 [localhost-startStop-1] ERROR context.GrailsContextLoaderListener - Error initializing the application: null id in usermanagement.UserWorkingTimeRegulation entry (don't flush the Session after an exception occurs)
Message: null id in usermanagement.UserWorkingTimeRegulation entry (don't flush the Session after an exception occurs)
Line | Method
->> 24 | doCall in usermanagement.UserWorkingTimeRegulation$__clinit__closure4$_closure8
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
| 47 | onApplicationEvent in org.grails.datastore.mapping.engine.event.AbstractPersistenceEventListener
| 52 | create . . . . . . . . . . . . . in usermanagement.UserWorkingTimeRegulation
| 47 | doCall in BootStrap$_closure1
| 327 | evaluateEnvironmentSpecificBlock in grails.util.Environment
| 320 | executeForEnvironment in ''
| 296 | executeForCurrentEnvironment . . in ''
| 266 | run in java.util.concurrent.FutureTask
| 1142 | runWorker . . . . . . . . . . . in java.util.concurrent.ThreadPoolExecutor
| 617 | run in java.util.concurrent.ThreadPoolExecutor$Worker
^ 745 | run . . . . . . . . . . . . . . in java.lang.Thread
Error |
Forked Grails VM exited with error
如果我使用在域 class 中声明的方法一切正常,则服务一定有问题。在另一个域中 class 我在自定义验证中使用了没有问题的服务,我不知道这个有什么特别之处。
编辑:
我在我的 Bootstrap.groovy
中创建了一个 UserWorkingTimeRegulation,如果我在我的域 class 中评论自定义验证,它会正确保存,因为服务正在返回 true
,它不应该做任何事情然后验证开始 false
.
Bootstrap:
UserWorkingTimeRegulation.create adminUser, workingTimeRegulation, new LocalDate(), new LocalDate().plusMonths(1)
默认情况下服务是事务性的 - 使服务成为非事务性的唯一方法是添加 static transactional = false
并删除所有 @Transactional
注释。 Spring/Hibernate 事务管理器总是在成功事务结束时刷新 Hibernate 会话,因此您所看到的是在调用服务方法(即使像您这样没有持久性的方法)之后,所有修改过的持久对象都是从 Hibernate 缓存刷新到数据库,但其中一个有问题。
错误消息相当含糊,但它表示 usermanagement.UserWorkingTimeRegulation
没有 ID。这意味着您调用了 save()
但它没有验证,因此您需要通过调用 hasErrors
and/or getErrors
检查哪些值丢失或无效。没有 id 是一个问题的原因是这个实例是另一个域对象的 属性,并且 id 被用作 link 它们在一起的外键。
p.s。随意删除未使用的自动生成的 serviceMethod
方法。
我正尝试在我的域 class 中使用一项服务进行自定义验证。在其他领域 classes 这很有效,但在这里我收到一个 Hibernate 断言错误。
域 class 自定义验证:
end validator: { val, obj ->
if (obj.userWorkingTimeRegulationService.validateit() == false){
return ["error.workingregulation"]
}
我使用以下方式注入服务:
def userWorkingTimeRegulationService
该服务仅 returns 用于测试目的:
package usermanagement
import grails.transaction.Transactional
@Transactional
class UserWorkingTimeRegulationService {
def serviceMethod() {
}
def validateit(){
return true
}
}
堆栈跟踪:
| Error 2015-05-27 15:07:54,909 [localhost-startStop-1] ERROR 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: null id in usermanagement.UserWorkingTimeRegulation entry (don't flush the Session after an exception occurs)
| Error 2015-05-27 15:07:54,927 [localhost-startStop-1] ERROR context.GrailsContextLoaderListener - Error initializing the application: null id in usermanagement.UserWorkingTimeRegulation entry (don't flush the Session after an exception occurs)
Message: null id in usermanagement.UserWorkingTimeRegulation entry (don't flush the Session after an exception occurs)
Line | Method
->> 24 | doCall in usermanagement.UserWorkingTimeRegulation$__clinit__closure4$_closure8
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
| 47 | onApplicationEvent in org.grails.datastore.mapping.engine.event.AbstractPersistenceEventListener
| 52 | create . . . . . . . . . . . . . in usermanagement.UserWorkingTimeRegulation
| 47 | doCall in BootStrap$_closure1
| 327 | evaluateEnvironmentSpecificBlock in grails.util.Environment
| 320 | executeForEnvironment in ''
| 296 | executeForCurrentEnvironment . . in ''
| 266 | run in java.util.concurrent.FutureTask
| 1142 | runWorker . . . . . . . . . . . in java.util.concurrent.ThreadPoolExecutor
| 617 | run in java.util.concurrent.ThreadPoolExecutor$Worker
^ 745 | run . . . . . . . . . . . . . . in java.lang.Thread
Error |
Forked Grails VM exited with error
如果我使用在域 class 中声明的方法一切正常,则服务一定有问题。在另一个域中 class 我在自定义验证中使用了没有问题的服务,我不知道这个有什么特别之处。
编辑:
我在我的 Bootstrap.groovy
中创建了一个 UserWorkingTimeRegulation,如果我在我的域 class 中评论自定义验证,它会正确保存,因为服务正在返回 true
,它不应该做任何事情然后验证开始 false
.
Bootstrap:
UserWorkingTimeRegulation.create adminUser, workingTimeRegulation, new LocalDate(), new LocalDate().plusMonths(1)
默认情况下服务是事务性的 - 使服务成为非事务性的唯一方法是添加 static transactional = false
并删除所有 @Transactional
注释。 Spring/Hibernate 事务管理器总是在成功事务结束时刷新 Hibernate 会话,因此您所看到的是在调用服务方法(即使像您这样没有持久性的方法)之后,所有修改过的持久对象都是从 Hibernate 缓存刷新到数据库,但其中一个有问题。
错误消息相当含糊,但它表示 usermanagement.UserWorkingTimeRegulation
没有 ID。这意味着您调用了 save()
但它没有验证,因此您需要通过调用 hasErrors
and/or getErrors
检查哪些值丢失或无效。没有 id 是一个问题的原因是这个实例是另一个域对象的 属性,并且 id 被用作 link 它们在一起的外键。
p.s。随意删除未使用的自动生成的 serviceMethod
方法。