Ошибки отображения Hibernate Grails 3 GORM, вызванные установщиками POJO - PullRequest
0 голосов
/ 08 сентября 2018

У меня есть отношения многие-ко-многим, которые не содержат ключевых слов hasMany и serveTo. Вместо этого мы используем рекомендации по производительности @burtbeckwith, объясненные здесь: https://www.youtube.com/watch?v=-nofscHeEuU и здесь: https://www.infoq.com/presentations/GORM-Performance

https://stackoverflow.com/users/160313/burt-beckwith

Отношение «многие ко многим» является однонаправленным и уникальным в том смысле, что в объекте Workout есть 3 свойства, которые сохраняют коллекции одного типа. Это стало возможным благодаря введению идентификатора в таблицу ссылок. (WorkoutMovementSet.groupIdentifier). Это решение отлично работает в Grails 2.3.11

class Workout extends BaseDomain{

    List<MovementSet> getMovementSets(){
        def joinedEntities = WorkoutMovementSet.findAllByWorkoutAndGroupIdentifier(this, null)
        return joinedEntities.sort { it.setIndex }.collect { it.movementSet } as List;
    }

    void setMovementSets(List<MovementSet> sets){
        sets.eachWithIndex { movementSet, index ->
            WorkoutMovementSet.create(this, movementSet, index)
        }
    }

    List<MovementSet> getCashIn(){
        return WorkoutMovementSet.findAllByWorkoutAndGroupIdentifier(this, "cashIn").sort { it.setIndex }.collect { it.movementSet } as List;
    }

    void setCashIn(List<MovementSet> sets){
        sets.eachWithIndex { movementSet, index ->
            WorkoutMovementSet.create(this, movementSet, index, "cashIn")
        }
    }

    List<MovementSet> getCashOut(){
        return WorkoutMovementSet.findAllByWorkoutAndGroupIdentifier(this, "cashOut").sort { it.setIndex }.collect { it.movementSet } as List;
    }

    void setCashOut(List<MovementSet> sets){
        sets.eachWithIndex { movementSet, index ->
            WorkoutMovementSet.create(this, movementSet, index, "cashOut")
        }
    }
}

И таблица ссылок ...

class WorkoutMovementSet implements Serializable{

    String id
    Workout workout
    MovementSet movementSet
    String groupIdentifier
    int setIndex

    static mapping = {
        id generator: 'uuid', params: [separator: '-']
        table 'workout_movementset'
        version false
    }

    static constraints = {
        groupIdentifier(nullable: true)
    }

    static WorkoutMovementSet create(Workout workout, MovementSet movementSet, int index, String groupId = null, boolean flush = false, failOnError = false) {
        WorkoutMovementSet instance = new WorkoutMovementSet(workout: workout, movementSet: movementSet, setIndex: index, groupIdentifier: groupId)
        instance.save(flush: flush, insert: true, failOnError: failOnError)
        return instance
    }

    static boolean remove(Workout workout, MovementSet movementSet, String groupId, boolean flush = false, failOnError = false) {
        WorkoutMovementSet instance = WorkoutMovementSet.findByWorkoutAndMovementSetAndGroupIdentifier(workout, movementSet, groupId)
        return instance ? instance.delete(flush: flush, failOnError: failOnError) : false
    }
}

После обновления с Grails 2.3.11 до Grails 3.3.8 эти отношения работают, только когда сеттеры в Workout удалены. В противном случае при отображении гибернации возникает следующее исключение при отображении:

org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'methodValidationPostProcessor' defined in class path resource [org/springframework/boot/autoconfigure/validation/ValidationAutoConfiguration.class]: Unsatisfied dependency expressed through method 'methodValidationPostProcessor' parameter 0; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'hibernateDatastoreServiceRegistry': Cannot resolve reference to bean 'hibernateDatastore' while setting constructor argument; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'hibernateDatastore': Bean instantiation via constructor failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.grails.orm.hibernate.HibernateDatastore]: Constructor threw exception; nested exception is org.hibernate.MappingException: collection element mapping has wrong number of columns: fitnerds.coreservices.domain.Workout.cashOut type: object
        at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:749)
        at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:467)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1181)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1075)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:513)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483)
        at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:312)
        at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
        at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:308)
        at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202)
        at org.springframework.context.support.PostProcessorRegistrationDelegate.registerBeanPostProcessors(PostProcessorRegistrationDelegate.java:225)
        at org.springframework.context.support.AbstractApplicationContext.registerBeanPostProcessors(AbstractApplicationContext.java:703)
        at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:528)
        at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:122)
        at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:693)
        at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:360)
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:303)
        at grails.boot.GrailsApp.run(GrailsApp.groovy:84)
        at grails.boot.GrailsApp.run(GrailsApp.groovy:393)
        at grails.boot.GrailsApp.run(GrailsApp.groovy:380)
        at grails.boot.GrailsApp$run.call(Unknown Source)
        at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:47)
        at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:116)
        at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:136)
        at tw.api.Application.main(Application.groovy:8)
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'hibernateDatastoreServiceRegistry': Cannot resolve reference to bean 'hibernateDatastore' while setting constructor argument; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'hibernateDatastore': Bean instantiation via constructor failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.grails.orm.hibernate.HibernateDatastore]: Constructor threw exception; nested exception is org.hibernate.MappingException: collection element mapping has wrong number of columns: fitnerds.coreservices.domain.Workout.cashOut type: object
        at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:359)
        at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:108)
        at org.springframework.beans.factory.support.ConstructorResolver.resolveConstructorArguments(ConstructorResolver.java:648)
        at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:145)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1201)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1103)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.getSingletonFactoryBeanForTypeCheck(AbstractAutowireCapableBeanFactory.java:931)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.getTypeForFactoryBean(AbstractAutowireCapableBeanFactory.java:808)
        at org.springframework.beans.factory.support.AbstractBeanFactory.isTypeMatch(AbstractBeanFactory.java:564)
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.doGetBeanNamesForType(DefaultListableBeanFactory.java:432)
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanNamesForType(DefaultListableBeanFactory.java:395)
        at org.springframework.beans.factory.BeanFactoryUtils.beanNamesForTypeIncludingAncestors(BeanFactoryUtils.java:206)
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.findAutowireCandidates(DefaultListableBeanFactory.java:1267)
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1101)
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1066)
        at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:835)
        at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:741)
        ... 24 common frames omitted
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'hibernateDatastore': Bean instantiation via constructor failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.grails.orm.hibernate.HibernateDatastore]: Constructor threw exception; nested exception is org.hibernate.MappingException: collection element mapping has wrong number of columns: fitnerds.coreservices.domain.Workout.cashOut type: object
        at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:279)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1201)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1103)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:513)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483)
        at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:312)
        at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
        at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:308)
        at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)
        at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:351)
        ... 40 common frames omitted
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.grails.orm.hibernate.HibernateDatastore]: Constructor threw exception; nested exception is org.hibernate.MappingException: collection element mapping has wrong number of columns: fitnerds.coreservices.domain.Workout.cashOut type: object
        at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:154)
        at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:122)
        at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:271)
        ... 49 common frames omitted
    Caused by: org.hibernate.MappingException: collection element mapping has wrong number of columns: fitnerds.coreservices.domain.Workout.cashOut type: object
            at org.hibernate.mapping.Collection.validate(Collection.java:315)
            at org.hibernate.mapping.IndexedCollection.validate(IndexedCollection.java:74)
            at org.hibernate.boot.internal.MetadataImpl.validate(MetadataImpl.java:333)
            at org.hibernate.boot.internal.SessionFactoryBuilderImpl.build(SessionFactoryBuilderImpl.java:464)
            at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:711)
            at org.grails.orm.hibernate.cfg.HibernateMappingContextConfiguration.buildSessionFactory(HibernateMappingContextConfiguration.java:276)
            at org.grails.orm.hibernate.connections.HibernateConnectionSourceFactory.create(HibernateConnectionSourceFactory.java:86)
            at org.grails.orm.hibernate.connections.AbstractHibernateConnectionSourceFactory.create(AbstractHibernateConnectionSourceFactory.java:39)
            at org.grails.orm.hibernate.connections.AbstractHibernateConnectionSourceFactory.create(AbstractHibernateConnectionSourceFactory.java:23)
            at org.grails.datastore.mapping.core.connections.AbstractConnectionSourceFactory.create(AbstractConnectionSourceFactory.java:64)
            at org.grails.datastore.mapping.core.connections.AbstractConnectionSourceFactory.create(AbstractConnectionSourceFactory.java:52)
            at org.grails.datastore.mapping.core.connections.ConnectionSourcesInitializer.create(ConnectionSourcesInitializer.groovy:24)
            at org.grails.orm.hibernate.HibernateDatastore.<init>(HibernateDatastore.java:201)
            at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
            at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
            at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
            at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
            at org.springsource.loaded.ri.ReflectiveInterceptor.jlrConstructorNewInstance(ReflectiveInterceptor.java:1076)
            at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:142)
            ... 51 common frames omitted

Я считаю, что шаги по воспроизведению этой проблемы должны включать отображение нескольких коллекций одного типа в объекте домена и с объявленными безопасными установщиками типов для коллекций. На данный момент я удалил свои сеттеры, но мы хотели бы сохранить их :)

Может быть, кто-то может просветить меня. Это вызвано множественными связями коллекций с одним и тем же типом, или он жалуется на дополнительные столбцы из-за дополнительного свойства groupIdentifier в таблице ссылок? Или что-то другое?

Версии программного обеспечения: Grails 3.3.8, Hibernate 5, Java 1.8.0_181

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...