使用hasMany
关系使用Grails关联映射时遇到了一个非常奇怪的问题。我们使用Grails 2.4.4和hibernate 3.6.10.18。
我们有三个域结构:
Person.groovy
package com.org
Person {
String email
Set<Favorite> favorites
List<Activity> activities
static hasMany = [favorites: Favorite, activities: Activity]
}
Favorite.groovy
package com.org
Favorite {
String name
static hasMany = [persons: Person]
static belongsTo = Person
}
Activity.groovy
package com.org
Activity {
String title
List<Favorite> favorites = []
static hasMany = [favorites: Favorite]
static belongsTo = [person: Person]
}
这个域结构在生产服务器上工作了很多年,当我们使用下面的代码时突然开始抛出一些异常:
Person personInstance = Parson.first() // Valid saved person instance
Activity acitivityInstnace = new Activity([title: "example"])
activityInstance.addToFavorites(Favorite.get(1)) // Both instance already exists
activityInstance.addToFavorites(Favorite.get(2))
activityInstance.setPerson(personInstance)
activityInstance.save()
println activityInstance.id
抛出的异常是(正在打印id):
2015-04-01 12:02:40,886 [http-bio-8080-exec-6] ERROR hibernate.AssertionFailure - 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: collection [com.org.Favorite.persons] was not processed by flush()
at org.grails.datastore.gorm.GormStaticApi$_methodMissing_closure2.doCall(GormStaticApi.groovy:102)
at com.org.ActivityService.save(ActivityService.groovy:50)
at com.org.ActivityController.save(ActivityController.groovy:137)
at grails.plugin.cache.web.filter.PageFragmentCachingFilter.doFilter(PageFragmentCachingFilter.java:200)
at grails.plugin.cache.web.filter.AbstractFilter.doFilter(AbstractFilter.java:63)
at grails.plugin.springsecurity.web.filter.GrailsAnonymousAuthenticationFilter.doFilter(GrailsAnonymousAuthenticationFilter.java:53)
at grails.plugin.springsecurity.web.authentication.RequestHolderAuthenticationFilter.doFilter(RequestHolderAuthenticationFilter.java:49)
at grails.plugin.springsecurity.web.authentication.logout.MutableLogoutFilter.doFilter(MutableLogoutFilter.java:82)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:744)
我尝试深入研究GormStaticApi
的代码并遵循一些代码,发现Favorite
域类的hasMany
和belongsTo
引用的映射无效。当我们从Favorite
域类中删除该映射时,不会发生异常。
为什么此代码之前运行,为什么我们无法在本地环境中重现此代码?在上次部署之前,没有任何改变。