grails / gorm-hibernate5

GORM for Hibernate 5
Apache License 2.0
66 stars 71 forks source link

Error with Multitenancy Domain class with inheritance #512

Open sdelamo opened 2 years ago

sdelamo commented 2 years ago

Add config:

grails:
    gorm:
        multiTenancy:
            mode: DISCRIMINATOR
            tenantResolverClass: org.grails.datastore.mapping.multitenancy.web.SessionTenantResolver

Add two domain classess:

package example

class Parent {
    String id
    String name
}
package example

import grails.gorm.MultiTenant
import org.codehaus.groovy.util.HashCodeHelper

class Child extends Parent implements MultiTenant<Child>, Serializable {

    String tenantId
    String description

    static mapping = {
        id generator: 'assigned', composite: ['id', 'tenantId']
    }

    @Override
    boolean equals(other) {
        if (other instanceof Child) {
            return other.id == id && other.tenantId == tenantId
        }
        false
    }

    int hashCode() {
        int hashCode = HashCodeHelper.initHash()
        if (id) {
            hashCode = HashCodeHelper.updateHash(hashCode, id)
        }
        if (tenantId) {
            hashCode = HashCodeHelper.updateHash(hashCode, tenantId)
        }
        hashCode
    }
}
./gradlew bootRun

> Task :bootRun
'2022-02-17 05:07:23.067 ERROR --- [  restartedMain] o.s.boot.SpringApplication               : Application run failed

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: property [tenantId] not found on entity [example.Child]
        at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:315)
        at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:296)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1372)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1222)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:582)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:542)
        at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335)
        at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234)
        at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333)
        at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208)
        at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:410)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1352)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1195)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:582)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:542)
        at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335)
        at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234)
        at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333)
        at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208)
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:953)
        at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:918)
        at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:583)
        at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:145)
        at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:730)
        at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:412)
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:302)
        at grails.boot.GrailsApp.run(GrailsApp.groovy:99)
        at grails.boot.GrailsApp.run(GrailsApp.groovy:485)
        at grails.boot.GrailsApp.run(GrailsApp.groovy:472)
        at multitenant.inheritance.Application.main(Application.groovy:11)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.base/java.lang.reflect.Method.invoke(Method.java:566)
        at org.springframework.boot.devtools.restart.RestartLauncher.run(RestartLauncher.java:49)
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.grails.orm.hibernate.HibernateDatastore]: Constructor threw exception; nested exception is org.hibernate.MappingException: property [tenantId] not found on entity [example.Child]
        at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:224)
        at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:117)
        at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:311)
        ... 34 common frames omitted
Caused by: org.hibernate.MappingException: property [tenantId] not found on entity [example.Child]
        at org.hibernate.mapping.PersistentClass.getProperty(PersistentClass.java:517)
        at org.hibernate.mapping.PersistentClass.getProperty(PersistentClass.java:528)
        at org.grails.orm.hibernate.cfg.GrailsDomainBinder.getProperty(GrailsDomainBinder.java:945)
        at org.grails.orm.hibernate.cfg.GrailsDomainBinder.addMultiTenantFilterIfNecessary(GrailsDomainBinder.java:1446)
        at org.grails.orm.hibernate.cfg.GrailsDomainBinder.bindSubClass(GrailsDomainBinder.java:1537)
        at org.grails.orm.hibernate.cfg.GrailsDomainBinder.bindSubClasses(GrailsDomainBinder.java:1467)
        at org.grails.orm.hibernate.cfg.GrailsDomainBinder.bindRoot(GrailsDomainBinder.java:1410)
        at org.grails.orm.hibernate.cfg.GrailsDomainBinder.contribute(GrailsDomainBinder.java:161)
        at org.hibernate.boot.model.process.spi.MetadataBuildingProcess.complete(MetadataBuildingProcess.java:292)
        at org.hibernate.boot.model.process.spi.MetadataBuildingProcess.build(MetadataBuildingProcess.java:86)
        at org.hibernate.boot.internal.MetadataBuilderImpl.build(MetadataBuilderImpl.java:479)
        at org.hibernate.boot.internal.MetadataBuilderImpl.build(MetadataBuilderImpl.java:85)
        at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:709)
        at org.grails.orm.hibernate.cfg.HibernateMappingContextConfiguration.buildSessionFactory(HibernateMappingContextConfiguration.java:287)
        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:212)
        at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
        at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
        at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
        at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:490)
        at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:211)
        ... 36 common frames omitted

Sample repository:

https://github.com/sdelamo/gorm-multitenancy-additional-tenant-query

I think this is related with:

https://github.com/grails/gorm-hibernate5/issues/450

daptordarattler commented 1 year ago

@sdelamo the referenced issue in #450 doesn't seem even close to your current issue. I wonder, were you able to resolve it and move on? What solution did you come up with?

I'm having the same issue. The only work around I have come up with is to use the database multi-tenant strategy. But i'm yet to implement that to confirm if it will work. I wish the discriminator strategy would be solved since it creates a simplicity for doing analytics on the data that I strongly need

sdelamo commented 1 year ago

I am not sure anymore.