Refresh doesn't work for entities which contains hasMany mapping.
- Dominant language
- Groovy
- Stars
- 2.9k
- Forks
- 975
- Avg merge
- 1d 22h
- Merged PRs (30d)
- 92
Description
After upgrade grails to version to 3.3.9 and GORM version to 6.1.10.RELEASE I've got error during refresh any entity which contains mapping like "hasMany".
Similar problem which I've found here is https://github.com/grails/grails-data-mapping/issues/1096, but no solution was provided.
Link to github(test application):
https://github.com/dmkolpakov/grails-data-mapping-issue-1210
Steps for reproduce:
Just run provided application from github repository above in HomeController issue will reproduced.
Please pay attention that I've specified access type for properties for entities in application.groovy.
import javax.persistence.*
grails.gorm.default.mapping = {
'*'(accessType: AccessType.PROPERTY)
}
According my investigation, problem happens because in new version trait DirtyCheckable was added for all domain's entities by default, if we use AccessType.PROPERTY, it invoke setter for certain property and mark entity as dirty, I'm not sure that is right, but more interesting is that hibernate can't proceed with it. I'm going to proceed my investigation, but if you have some thoughts please advise to me.
```
For example:
class Vehicle {
Integer year
String name
Model model
Make make
static hasMany = [owners: Owner]
static constraints = {
year min: 1900
name maxSize: 255
}
}
....
def vehicle = Vehicle.findByName("Pickup")
vehicle.refresh()
```
Exception example:
```
java.lang.reflect.InvocationTargetException: null
at org.grails.core.DefaultGrailsControllerClass$ReflectionInvoker.invoke(DefaultGrailsControllerClass.java:211)
at org.grails.core.DefaultGrailsControllerClass.invoke(DefaultGrailsControllerClass.java:188)
at org.grails.web.mapping.mvc.UrlMappingsInfoHandlerAdapter.handle(UrlMappingsInfoHandlerAdapter.groovy:90)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:967)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:901)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970)
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:861)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846)
at org.springframework.boot.web.filter.ApplicationContextHeaderFilter.doFilterInternal(ApplicationContextHeaderFilter.java:55)
at org.grails.web.servlet.mvc.GrailsWebRequestFilter.doFilterInternal(GrailsWebRequestFilter.java:77)
at org.grails.web.filters.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:67)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
Caused by: org.springframework.orm.hibernate5.HibernateSystemException: Exception occurred inside setter of org.grails.guides.Vehicle.owners; nested exception is org.hibernate.PropertyAccessException: Exception occurred inside setter of org.grails.guides.Vehicle.owners
at org.springframework.orm.hibernate5.SessionFactoryUtils.convertHibernateAccessException(SessionFactoryUtils.java:296)
at org.grails.orm.hibernate.GrailsHibernateTemplate.convertHibernateAccessException(GrailsHibernateTemplate.java:724)
at org.grails.orm.hibernate.GrailsHibernateTemplate.doExecute(GrailsHibernateTemplate.java:303)
at org.grails.orm.hibernate.GrailsHibernateTemplate.refresh(GrailsHibernateTemplate.java:457)
at org.grails.orm.hibernate.GrailsHibernateTemplate.refresh(GrailsHibernateTemplate.java:453)
at org.grails.orm.hibernate.AbstractHibernateGormInstanceApi.refresh(AbstractHibernateGormInstanceApi.groovy:241)
at org.grails.datastore.gorm.GormEntity$Trait$Helper.refresh(GormEntity.groovy:90)
at org.grails.guides.HomeController.index(HomeController.groovy:7)
... 14 common frames omitted
Caused by: org.hibernate.PropertyAccessException: Exception occurred inside setter of org.grails.guides.Vehicle.owners
at org.hibernate.property.access.spi.SetterMethodImpl.set(SetterMethodImpl.java:67)
at org.hibernate.tuple.entity.AbstractEntityTuplizer.setPropertyValues(AbstractEntityTuplizer.java:664)
at org.hibernate.tuple.entity.PojoEntityTuplizer.setPropertyValues(PojoEntityTuplizer.java:207)
at org.hibernate.persister.entity.AbstractEntityPersister.setPropertyValues(AbstractEntityPersister.java:4692)
at org.hibernate.engine.internal.TwoPhaseLoad.doInitializeEntity(TwoPhaseLoad.java:183)
at org.hibernate.engine.internal.TwoPhaseLoad.initializeEntity(TwoPhaseLoad.java:125)
at org.hibernate.loader.Loader.initializeEntitiesAndCollections(Loader.java:1139)
at org.hibernate.loader.Loader.processResultSet(Loader.java:998)
at org.hibernate.loader.Loader.doQuery(Loader.java:936)
at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:342)
at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:312)
at org.hibernate.loader.Loader.loadEntity(Loader.java:2209)
at org.hibernate.loader.entity.AbstractEntityLoader.load(AbstractEntityLoader.java:60)
at org.hibernate.loader.entity.AbstractEntityLoader.load(AbstractEntityLoader.java:50)
at org.hibernate.persister.entity.AbstractEntityPersister.load(AbstractEntityPersister.java:4069)
at org.hibernate.event.internal.DefaultRefreshEventListener.onRefresh(DefaultRefreshEventListener.java:171)
at org.hibernate.event.internal.DefaultRefreshEventListener.onRefresh(DefaultRefreshEventListener.java:48)
at org.hibernate.internal.SessionImpl.fireRefresh(SessionImpl.java:1193)
at org.hibernate.internal.SessionImpl.refresh(SessionImpl.java:1166)
at org.hibernate.internal.SessionImpl.refresh(SessionImpl.java:1161)
at org.grails.orm.hibernate.GrailsHibernateTemplate$11.doInHibernate(GrailsHibernateTemplate.java:460)
at org.grails.orm.hibernate.GrailsHibernateTemplate.doExecute(GrailsHibernateTemplate.java:299)
... 19 common frames omitted
Caused by: java.lang.reflect.InvocationTargetException: null
at org.hibernate.property.access.spi.SetterMethodImpl.set(SetterMethodImpl.java:44)
... 40 common frames omitted
Caused by: org.hibernate.LazyInitializationException: failed to lazily initialize a collection, no session or session was closed
at org.hibernate.collection.internal.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:584)
at org.hibernate.collection.internal.AbstractPersistentCollection.throwLazyInitializationExceptionIfNotConnected(AbstractPersistentCollection.java:576)
at org.hibernate.collection.internal.AbstractPersistentCollection.access$200(AbstractPersistentCollection.java:55)
at org.hibernate.collection.internal.AbstractPersistentCollection$1.doWork(AbstractPersistentCollection.java:165)
at org.hibernate.collection.internal.AbstractPersistentCollection$1.doWork(AbstractPersistentCollection.java:146)
at org.hibernate.collection.internal.AbstractPersistentCollection.withTemporarySessionIfNeeded(AbstractPersistentCollection.java:249)
at org.hibernate.collection.internal.AbstractPersistentCollection.readSize(AbstractPersistentCollection.java:145)
at org.hibernate.collection.internal.PersistentSet.size(PersistentSet.java:143)
at org.grails.datastore.mapping.dirty.checking.DirtyCheckable$Trait$Helper.markDirty(DirtyCheckable.groovy:81)
... 41 common frames omitted
```
### Task List
- [x] Steps to reproduce provided
- [x] Stacktrace (if present) provided
- [x] Example that reproduces the problem uploaded to Github
- [x] Full description of the issue provided (see below)
### Environment Information
- **Operating System**: Windows 7 Professional
- **GORM Version:** 6.1.10.RELEASE
- **Grails Version (if using Grails):** 3.3.9
- **JDK Version:** java8_191
Contributor guide
Research direction
Reproduce the failure from the linked test application, starting at HomeController.index with the Vehicle entity's hasMany owners mapping and AccessType.PROPERTY configuration. Inspect the refresh call and the provided stack trace, especially DirtyCheckable.markDirty and the Vehicle.owners setter path. Done means refreshing the entity no longer raises the reported LazyInitializationException.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- groovy
- Domain
- backend, database
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 30/100