Grails GORM выдает исключение гибернации при запросе объекта домена, который уже был запрошен

У меня есть приложение Grails, в котором контроллер вызывает транзакционную службу. Служба имеет следующее тело

def rep = Rep.findById(2708280)

def r = Rep.findById(2708280)
r.accountNumber = "123423565476"
r.save(failOnError: true)

def list = Rep.findAllByRtnAndAccountNumber(
        rep.rtn, rep.accountNumber)

Когда вызывается последняя строка в методе, я получаю следующее исключение гибернации:

    ERROR an assertion failure occured (this may indicate a bug in Hibernate, but is more likely due to unsafe use of the session) [AssertionFailure]
org.hibernate.AssertionFailure: collection [com.mydomain.InnerObject.assignedTests] was not processed by flush()
at org.hibernate.engine.CollectionEntry.postFlush(CollectionEntry.java:228)
at org.hibernate.event.def.AbstractFlushingEventListener.postFlush(AbstractFlushingEventListener.java:352)
at org.hibernate.event.def.DefaultAutoFlushEventListener.onAutoFlush(DefaultAutoFlushEventListener.java:65)
at org.hibernate.impl.SessionImpl.autoFlushIfRequired(SessionImpl.java:1185)
at org.hibernate.impl.SessionImpl.list(SessionImpl.java:1709)
at org.hibernate.impl.CriteriaImpl.list(CriteriaImpl.java:347)
at org.codehaus.groovy.grails.orm.hibernate.metaclass.FindAllByPersistentMethod$1.doInHibernate(FindAllByPersistentMethod.java:113)
at org.springframework.orm.hibernate3.HibernateTemplate.doExecute(HibernateTemplate.java:411)
at org.springframework.orm.hibernate3.HibernateTemplate.executeFind(HibernateTemplate.java:348)
at org.codehaus.groovy.grails.orm.hibernate.metaclass.FindAllByPersistentMethod.doInvokeInternalWithExpressions(FindAllByPersistentMethod.java:73)
at org.codehaus.groovy.grails.orm.hibernate.metaclass.AbstractClausedStaticPersistentMethod.doInvokeInternal(AbstractClausedStaticPersistentMethod.java:543)
at org.codehaus.groovy.grails.orm.hibernate.metaclass.AbstractClausedStaticPersistentMethod.doInvokeInternal(AbstractClausedStaticPersistentMethod.java:417)
at org.codehaus.groovy.grails.orm.hibernate.metaclass.AbstractStaticPersistentMethod.invoke(AbstractStaticPersistentMethod.java:79)
at org.codehaus.groovy.grails.orm.hibernate.metaclass.AbstractStaticPersistentMethod.invoke(AbstractStaticPersistentMethod.java:72)
at sun.reflect.GeneratedMethodAccessor9819.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java)
at java.lang.reflect.Method.invoke(Method.java:497)
at org.codehaus.groovy.runtime.callsite.PojoMetaMethodSite$PojoCachedMethodSiteNoUnwrapNoCoerce.invoke(PojoMetaMethodSite.java:233)
at org.codehaus.groovy.runtime.callsite.PojoMetaMethodSite.call(PojoMetaMethodSite.java:56)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:48)
at org.codehaus.groovy.runtime.callsite.PojoMetaMethodSite.call(PojoMetaMethodSite.java:58)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:141)
at org.grails.datastore.gorm.GormStaticApi$_methodMissing_closure2.doCall(GormStaticApi.groovy:102)
at org.grails.datastore.gorm.GormStaticApi$_methodMissing_closure2.call(GormStaticApi.groovy)
at org.codehaus.groovy.runtime.metaclass.ClosureStaticMetaMethod.invoke(ClosureStaticMetaMethod.java:62)
at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:325)
at org.codehaus.groovy.runtime.callsite.StaticMetaMethodSite.invoke(StaticMetaMethodSite.java:46)
at org.codehaus.groovy.runtime.callsite.StaticMetaMethodSite.call(StaticMetaMethodSite.java:91)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:48)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:113)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:133)
at com.mydomaint.MyService.$tt__process(MyService.groovy:118)

где «com.mydomain.InnerObject» — это внутренний объект моего объекта домена выше.

static belongsTo = [owner: InnerObject]

InnerObject owner

иassignedTests является свойством домена InnerObject:

static hasMany = [assignedVouchers: AssignedTests]

Есть ли что-то, что мне здесь не хватает? Что означает это исключение?


person Sergei Ledvanov    schedule 19.02.2016    source источник
comment
Проблема исчезнет, ​​если вы измените r.save(failOnError: true) на r.save(failOnError: true, flush: true)?   -  person Jeff Scott Brown    schedule 19.02.2016
comment
И да и нет. У меня есть 3k таких доменных объектов, которые обрабатываются в цикле, и в какой-то момент это происходит со мной снова. Хотя с flush:true это случается реже.   -  person Sergei Ledvanov    schedule 19.02.2016


Ответы (1)


Это происходит, вероятно, потому, что у вас есть два объекта одного и того же экземпляра в сеансе с разными значениями.

rep не изменяется, а r изменяется (и сохраняется)

Когда вы вызываете list, Hibernate пытается сбросить сеанс и путается

at org.hibernate.engine.CollectionEntry.postFlush(CollectionEntry.java:228)
at org.hibernate.event.def.AbstractFlushingEventListener.postFlush(AbstractFlushingEventListener.java:352)
at org.hibernate.event.def.DefaultAutoFlushEventListener.onAutoFlush(DefaultAutoFlushEventListener.java:65)
at org.hibernate.impl.SessionImpl.autoFlushIfRequired(SessionImpl.java:1185)
at org.hibernate.impl.SessionImpl.list(SessionImpl.java:1709)

Вместо этого вы можете попытаться сохранить параметры, которые вы передаете в список, в отдельных переменных. Попробуй это:

def r = Rep.findById(2708280)
def p1 = r.rtn
def p2 = r.accountNumber

r.accountNumber = "123423565476"
r.save(failOnError: true)

def list = Rep.findAllByRtnAndAccountNumber(p1, p2)
person Paulo Henrique    schedule 19.02.2016