Skip to content

Refresh doesn't work for entities which contains hasMany mapping. #14534

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
4 tasks done
dmkolpakov opened this issue Dec 27, 2018 · 5 comments
Open
4 tasks done

Refresh doesn't work for entities which contains hasMany mapping. #14534

dmkolpakov opened this issue Dec 27, 2018 · 5 comments

Comments

@dmkolpakov
Copy link

dmkolpakov commented Dec 27, 2018

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 apache/grails-data-mapping#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

  • Steps to reproduce provided
  • Stacktrace (if present) provided
  • Example that reproduces the problem uploaded to Github
  • 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
@dmkolpakov
Copy link
Author

dmkolpakov commented Dec 30, 2018

Description of issue has been updated.

@demon101
Copy link
Contributor

demon101 commented Jan 7, 2019

@graemerocher in our project we have the same bug with disabled new dirty checking.

hibernate:
    hibernateDirtyChecking: true 

I have checked on https://github.com/dmkolpakov/grails-data-mapping-issue-1210 , the bug still exist with hibernateDirtyChecking: true

By the way, looks like unnecessary dirty checking during refreshing:
screenshot from 2019-01-07 13-35-38

@demon101
Copy link
Contributor

looks like a big regression.
Now refresh() working only in simple cases.

As a workaround (thx @dmkolpakov ) empty method trackChanges can be added to the parent class

class Parent implements DirtyCheckable {
    static hasMany = [child: Child]
    void trackChanges() {
        // not track changes
    }
}

But in this case, as I understand parent class become non-DirtyCheckable

@dmkolpakov dmkolpakov changed the title org.hibernate.LazyInitializationException for entities which contains hasMany mapping. Refresh doesn't work for entities which contains hasMany mapping. Jan 17, 2019
@demon101
Copy link
Contributor

don't use

grails.gorm.default.mapping = {
    '*'(accessType: AccessType.PROPERTY)
}

@developerrgm
Copy link

I am also facing same problem.
hibernate: hibernateDirtyChecking: true
did not help. Any update?

@jdaugherty jdaugherty transferred this issue from apache/grails-data-mapping Apr 22, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants