Extends TenantProvider error when building

I extend TenantProvider interface and ExtMultiTenantProviderBean bean.


public interface ExtTenantProvider extends TenantProvider {

    String NAME = "imdp_TenantProvider";

    /**
     * User tenant type: TENANT/CUSTOMER/NO_TENANT.
     */
    String USER_TENANT_TYPE = "userTenantType";
    String TENANT = "tenant";
    String CUSTOMER = "customer";
	
    /**
     * Provides the current tenant type for save to user session.
     *
     * @return the current tenant type.
     */
    String getCurrentUserTenantType();
}

@Component(ExtTenantProvider.NAME)
public class ExtMultiTenantProviderBean implements ExtTenantProvider {

    @Inject
    private UserSessionSource userSessionSource;

    /**
     * Returns the tenant ID of a logged in user.
     *
     * @return tenant ID of a logged in user, 'no_tenant' if the user doesn't have a tenant ID
     */
    @Override
    public String getCurrentUserTenantId() {
        if (userSessionSource.checkCurrentUserSession() && userSessionSource.getUserSession().getAttribute(TENANT_ID_ATTRIBUTE_NAME) != null) {
            return userSessionSource.getUserSession().getAttribute(TENANT_ID_ATTRIBUTE_NAME);
        }
        return NO_TENANT;
    }

    @Override
    public String getCurrentUserTenantType() {
        if (userSessionSource.checkCurrentUserSession() && userSessionSource.getUserSession().getAttribute(USER_TENANT_TYPE) != null) {
            return userSessionSource.getUserSession().getAttribute(USER_TENANT_TYPE);
        }
        return NO_TENANT;
    }
}

and register the class in spring.xml

 <bean id="cubasdbmt_TenantProvider" class="com.kaixin.imdp.entity.sys.security.multitenancy.ExtMultiTenantProviderBean"/>

but, when I build the project, I get following error

23:33:46.850 WARN  c.h.c.c.s.CubaClassPathXmlApplicationContext- Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'cubasdbmt_MultiTenancyTools': Unsatisfied dependency expressed through field 'tenantProvider'; nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'com.haulmont.addon.sdbmt.core.app.multitenancy.TenantProvider' available: expected single matching bean but found 2: cubasdbmt_TenantProvider,imdp_TenantProvider
23:33:46.850 INFO  c.h.c.c.s.CubaThreadPoolTaskScheduler   - Shutting down ExecutorService 'scheduler'
23:33:46.870 ERROR c.h.c.c.s.AbstractWebAppContextLoader   - Error initializing application
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'cubasdbmt_MultiTenancyTools': Unsatisfied dependency expressed through field 'tenantProvider'; nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'com.haulmont.addon.sdbmt.core.app.multitenancy.TenantProvider' available: expected single matching bean but found 2: cubasdbmt_TenantProvider,imdp_TenantProvider
	at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:643) ~[spring-beans-5.2.3.RELEASE.jar:5.2.3.RELEASE]
	at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:116) ~[spring-beans-5.2.3.RELEASE.jar:5.2.3.RELEASE]
	at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessProperties(AutowiredAnnotationBeanPostProcessor.java:399) ~[spring-beans-5.2.3.RELEASE.jar:5.2.3.RELEASE]
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1422) ~[spring-beans-5.2.3.RELEASE.jar:5.2.3.RELEASE]

What’s wrong about my code? And how can I fix this error?
Thanks!

Hi @jkwoocn,

What wrong is explicitly explained in the logs here:
No qualifying bean of type 'com.haulmont.addon.sdbmt.core.app.multitenancy.TenantProvider' available: expected single matching bean but found 2: cubasdbmt_TenantProvider,imdp_TenantProvider at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:643) ~[spring-beans-5.2.3.RELEASE.jar:5.2.3.RELEASE]

You have two components, that satisfy the TenantProvider interface.

The easiest way to resolve the issue I guess is to remove @Component(ExtTenantProvider.NAME) over your ExtMultiTenantProviderBean implementation.

I also notice that you have copied the entire implementation from the MultiTenantProviderBean. I would implement it as follows:

public class ExtMultiTenantProviderBean extends MultiTenantProviderBean {
    private final String USER_TENANT_TYPE = "userTenantType";

    @Inject
    private UserSessionSource userSessionSource;

    public String getCurrentUserTenantType() {
        if (userSessionSource.checkCurrentUserSession() && userSessionSource.getUserSession().getAttribute(USER_TENANT_TYPE) != null) {
            return userSessionSource.getUserSession().getAttribute(USER_TENANT_TYPE);
        }
        return NO_TENANT;
    }
}

No need for any additional interface, also we avoid copy-paste by subclassing the original implementation.

From your sources you can use it as:

    @Inject
    private TenantProvider tenantProvider;
    
    public void foo() {
        ExtMultiTenantProviderBean extTenantProvider = (ExtMultiTenantProviderBean) tenantProvider;
    }

Regards,
Aleksey

Thank you!
I remove @Component(ExtTenantProvider.NAME) and re-write my code.
It’s OK now.
:slight_smile:

1 Like