sunitk / multitenancy-dynamic-tenant Goto Github PK
View Code? Open in Web Editor NEWSpring Boot 2 JPA Hibernate with database per tenant with dynamic configuration of tenants, secured by Spring Security
License: Apache License 2.0
Spring Boot 2 JPA Hibernate with database per tenant with dynamic configuration of tenants, secured by Spring Security
License: Apache License 2.0
While load testing if only 5 user concurrently logging in the application it fails to get connection due to connection timeout.
Hi Sunitk,
Thank you for this greate post. I clone this project and make it worked for multi tenant case. However, it seems like Hibernate only auto update schema in the first tenant datasource and I'm not sure where I went wrong. Here is spring's log
2018-12-11 14:25:38.398 INFO 3444 --- [ main] .S.SpringDataMultiTenantMySqlApplication : Starting SpringDataMultiTenantMySqlApplication on xhdeMacBook-Air-5.local with PID 3444 (/Users/xh/dev/SpringDataMultiTenantMySQL/out/production/classes started by xh in /Users/xh/dev/SpringDataMultiTenantMySQL)
2018-12-11 14:25:38.406 INFO 3444 --- [ main] .S.SpringDataMultiTenantMySqlApplication : The following profiles are active: dev
2018-12-11 14:25:38.660 INFO 3444 --- [ main] ationConfigEmbeddedWebApplicationContext : Refreshing org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@402bba4f: startup date [Tue Dec 11 14:25:38 CST 2018]; root of context hierarchy
2018-12-11 14:25:40.547 INFO 3444 --- [ main] f.a.AutowiredAnnotationBeanPostProcessor : JSR-330 'javax.inject.Inject' annotation found and supported for autowiring
2018-12-11 14:25:40.618 INFO 3444 --- [ main] trationDelegate$BeanPostProcessorChecker : Bean 'masterDatabaseConfig' of type [com.zhtangsh.SpringDataMultiTenantMySQL.master.config.MasterDatabaseConfig$$EnhancerBySpringCGLIB$$adef62c7] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2018-12-11 14:25:41.556 INFO 3444 --- [ main] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat initialized with port(s): 8800 (http)
2018-12-11 14:25:41.651 INFO 3444 --- [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat]
2018-12-11 14:25:41.652 INFO 3444 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet Engine: Apache Tomcat/8.5.35
2018-12-11 14:25:41.941 INFO 3444 --- [ost-startStop-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
2018-12-11 14:25:41.941 INFO 3444 --- [ost-startStop-1] o.s.web.context.ContextLoader : Root WebApplicationContext: initialization completed in 3288 ms
2018-12-11 14:25:42.223 INFO 3444 --- [ost-startStop-1] c.z.S.m.config.MasterDatabaseConfig : Start setting up master EntityManagerFactory
2018-12-11 14:25:42.237 INFO 3444 --- [ost-startStop-1] c.z.S.m.config.MasterDatabaseConfig : Start setting up master datasource
2018-12-11 14:25:42.251 INFO 3444 --- [ost-startStop-1] c.z.S.m.config.MasterDatabaseConfig : Finish setting up master datasource
2018-12-11 14:25:42.381 INFO 3444 --- [ost-startStop-1] c.z.S.m.config.MasterDatabaseConfig : Finish setting up master EntityManagerFactory
2018-12-11 14:25:42.426 INFO 3444 --- [ost-startStop-1] j.LocalContainerEntityManagerFactoryBean : Building JPA container EntityManagerFactory for persistence unit 'master-persistence-unit'
2018-12-11 14:25:42.464 INFO 3444 --- [ost-startStop-1] o.hibernate.jpa.internal.util.LogHelper : HHH000204: Processing PersistenceUnitInfo [
name: master-persistence-unit
...]
2018-12-11 14:25:42.666 INFO 3444 --- [ost-startStop-1] org.hibernate.Version : HHH000412: Hibernate Core {5.0.12.Final}
2018-12-11 14:25:42.670 INFO 3444 --- [ost-startStop-1] org.hibernate.cfg.Environment : HHH000206: hibernate.properties not found
2018-12-11 14:25:42.673 INFO 3444 --- [ost-startStop-1] org.hibernate.cfg.Environment : HHH000021: Bytecode provider name : javassist
2018-12-11 14:25:42.750 INFO 3444 --- [ost-startStop-1] o.hibernate.annotations.common.Version : HCANN000001: Hibernate Commons Annotations {5.0.1.Final}
2018-12-11 14:25:42.968 WARN 3444 --- [ost-startStop-1] com.zaxxer.hikari.HikariConfig : {} - idleTimeout has been set but has no effect because the pool is operating as a fixed size pool.
2018-12-11 14:25:42.968 INFO 3444 --- [ost-startStop-1] com.zaxxer.hikari.HikariDataSource : master-connection-pool - Starting...
Tue Dec 11 14:25:43 CST 2018 WARN: Establishing SSL connection without server's identity verification is not recommended. According to MySQL 5.5.45+, 5.6.26+ and 5.7.6+ requirements SSL connection must be established by default if explicit option isn't set. For compliance with existing applications not using SSL the verifyServerCertificate property is set to 'false'. You need either to explicitly disable SSL by setting useSSL=false, or set useSSL=true and provide truststore for server certificate verification.
2018-12-11 14:25:43.979 INFO 3444 --- [ost-startStop-1] com.zaxxer.hikari.HikariDataSource : master-connection-pool - Start completed.
2018-12-11 14:25:44.000 INFO 3444 --- [ost-startStop-1] org.hibernate.dialect.Dialect : HHH000400: Using dialect: org.hibernate.dialect.MySQL5Dialect
Tue Dec 11 14:25:44 CST 2018 WARN: Establishing SSL connection without server's identity verification is not recommended. According to MySQL 5.5.45+, 5.6.26+ and 5.7.6+ requirements SSL connection must be established by default if explicit option isn't set. For compliance with existing applications not using SSL the verifyServerCertificate property is set to 'false'. You need either to explicitly disable SSL by setting useSSL=false, or set useSSL=true and provide truststore for server certificate verification.
Tue Dec 11 14:25:44 CST 2018 WARN: Establishing SSL connection without server's identity verification is not recommended. According to MySQL 5.5.45+, 5.6.26+ and 5.7.6+ requirements SSL connection must be established by default if explicit option isn't set. For compliance with existing applications not using SSL the verifyServerCertificate property is set to 'false'. You need either to explicitly disable SSL by setting useSSL=false, or set useSSL=true and provide truststore for server certificate verification.
Tue Dec 11 14:25:44 CST 2018 WARN: Establishing SSL connection without server's identity verification is not recommended. According to MySQL 5.5.45+, 5.6.26+ and 5.7.6+ requirements SSL connection must be established by default if explicit option isn't set. For compliance with existing applications not using SSL the verifyServerCertificate property is set to 'false'. You need either to explicitly disable SSL by setting useSSL=false, or set useSSL=true and provide truststore for server certificate verification.
Tue Dec 11 14:25:44 CST 2018 WARN: Establishing SSL connection without server's identity verification is not recommended. According to MySQL 5.5.45+, 5.6.26+ and 5.7.6+ requirements SSL connection must be established by default if explicit option isn't set. For compliance with existing applications not using SSL the verifyServerCertificate property is set to 'false'. You need either to explicitly disable SSL by setting useSSL=false, or set useSSL=true and provide truststore for server certificate verification.
2018-12-11 14:25:44.891 INFO 3444 --- [ost-startStop-1] org.hibernate.tool.hbm2ddl.SchemaUpdate : HHH000228: Running hbm2ddl schema update
2018-12-11 14:25:45.161 INFO 3444 --- [ost-startStop-1] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'master-persistence-unit'
2018-12-11 14:25:45.543 INFO 3444 --- [ost-startStop-1] o.h.h.i.QueryTranslatorFactoryInitiator : HHH000397: Using ASTQueryTranslatorFactory
2018-12-11 14:25:45.744 INFO 3444 --- [ost-startStop-1] c.z.S.tenant.config.TenantDtabaseConfig : Start the configuration of tenantEntityManagerFactory
2018-12-11 14:25:45.762 INFO 3444 --- [ost-startStop-1] c.z.S.tenant.config.TenantDtabaseConfig : End pf tenantEntityManagerFactory setup
2018-12-11 14:25:45.769 INFO 3444 --- [ost-startStop-1] j.LocalContainerEntityManagerFactoryBean : Building JPA container EntityManagerFactory for persistence unit 'tenantdb-persistence-unit'
2018-12-11 14:25:45.769 INFO 3444 --- [ost-startStop-1] o.hibernate.jpa.internal.util.LogHelper : HHH000204: Processing PersistenceUnitInfo [
name: tenantdb-persistence-unit
...]
Hibernate:
select
mastertena0_.id as id1_0_,
mastertena0_.password as password2_0_,
mastertena0_.tenant_id as tenant_i3_0_,
mastertena0_.url as url4_0_,
mastertena0_.username as username5_0_,
mastertena0_.version as version6_0_
from
master_tenant mastertena0_
2018-12-11 14:25:46.037 INFO 3444 --- [ost-startStop-1] ceBasedMultiTenantConnectionProviderImpl : selectAnyDataSource() -- total tenants: 2
2018-12-11 14:25:46.040 INFO 3444 --- [ost-startStop-1] c.z.S.util.DataSourceUtil : Configured datasource: {}
2018-12-11 14:25:46.041 INFO 3444 --- [ost-startStop-1] c.z.S.util.DataSourceUtil : Configured datasource: {}
2018-12-11 14:25:46.041 INFO 3444 --- [ost-startStop-1] com.zaxxer.hikari.HikariDataSource : cc-connection-pool - Starting...
Tue Dec 11 14:25:46 CST 2018 WARN: Establishing SSL connection without server's identity verification is not recommended. According to MySQL 5.5.45+, 5.6.26+ and 5.7.6+ requirements SSL connection must be established by default if explicit option isn't set. For compliance with existing applications not using SSL the verifyServerCertificate property is set to 'false'. You need either to explicitly disable SSL by setting useSSL=false, or set useSSL=true and provide truststore for server certificate verification.
2018-12-11 14:25:46.142 INFO 3444 --- [ost-startStop-1] com.zaxxer.hikari.HikariDataSource : cc-connection-pool - Start completed.
2018-12-11 14:25:46.142 INFO 3444 --- [ost-startStop-1] org.hibernate.dialect.Dialect : HHH000400: Using dialect: org.hibernate.dialect.MySQL5Dialect
2018-12-11 14:25:46.218 INFO 3444 --- [ost-startStop-1] org.hibernate.tool.hbm2ddl.SchemaUpdate : HHH000228: Running hbm2ddl schema update
Tue Dec 11 14:25:46 CST 2018 WARN: Establishing SSL connection without server's identity verification is not recommended. According to MySQL 5.5.45+, 5.6.26+ and 5.7.6+ requirements SSL connection must be established by default if explicit option isn't set. For compliance with existing applications not using SSL the verifyServerCertificate property is set to 'false'. You need either to explicitly disable SSL by setting useSSL=false, or set useSSL=true and provide truststore for server certificate verification.
Tue Dec 11 14:25:46 CST 2018 WARN: Establishing SSL connection without server's identity verification is not recommended. According to MySQL 5.5.45+, 5.6.26+ and 5.7.6+ requirements SSL connection must be established by default if explicit option isn't set. For compliance with existing applications not using SSL the verifyServerCertificate property is set to 'false'. You need either to explicitly disable SSL by setting useSSL=false, or set useSSL=true and provide truststore for server certificate verification.
2018-12-11 14:25:46.296 INFO 3444 --- [ost-startStop-1] rmationExtractorJdbcDatabaseMetaDataImpl : HHH000262: Table not found: Company
2018-12-11 14:25:46.306 INFO 3444 --- [ost-startStop-1] rmationExtractorJdbcDatabaseMetaDataImpl : HHH000262: Table not found: Company
Tue Dec 11 14:25:46 CST 2018 WARN: Establishing SSL connection without server's identity verification is not recommended. According to MySQL 5.5.45+, 5.6.26+ and 5.7.6+ requirements SSL connection must be established by default if explicit option isn't set. For compliance with existing applications not using SSL the verifyServerCertificate property is set to 'false'. You need either to explicitly disable SSL by setting useSSL=false, or set useSSL=true and provide truststore for server certificate verification.
Tue Dec 11 14:25:46 CST 2018 WARN: Establishing SSL connection without server's identity verification is not recommended. According to MySQL 5.5.45+, 5.6.26+ and 5.7.6+ requirements SSL connection must be established by default if explicit option isn't set. For compliance with existing applications not using SSL the verifyServerCertificate property is set to 'false'. You need either to explicitly disable SSL by setting useSSL=false, or set useSSL=true and provide truststore for server certificate verification.
Tue Dec 11 14:25:46 CST 2018 WARN: Establishing SSL connection without server's identity verification is not recommended. According to MySQL 5.5.45+, 5.6.26+ and 5.7.6+ requirements SSL connection must be established by default if explicit option isn't set. For compliance with existing applications not using SSL the verifyServerCertificate property is set to 'false'. You need either to explicitly disable SSL by setting useSSL=false, or set useSSL=true and provide truststore for server certificate verification.
Tue Dec 11 14:25:46 CST 2018 WARN: Establishing SSL connection without server's identity verification is not recommended. According to MySQL 5.5.45+, 5.6.26+ and 5.7.6+ requirements SSL connection must be established by default if explicit option isn't set. For compliance with existing applications not using SSL the verifyServerCertificate property is set to 'false'. You need either to explicitly disable SSL by setting useSSL=false, or set useSSL=true and provide truststore for server certificate verification.
2018-12-11 14:25:47.501 INFO 3444 --- [ost-startStop-1] rmationExtractorJdbcDatabaseMetaDataImpl : HHH000262: Table not found: Currency
2018-12-11 14:25:47.507 INFO 3444 --- [ost-startStop-1] rmationExtractorJdbcDatabaseMetaDataImpl : HHH000262: Table not found: Currency
2018-12-11 14:25:48.367 INFO 3444 --- [ost-startStop-1] rmationExtractorJdbcDatabaseMetaDataImpl : HHH000262: Table not found: User
2018-12-11 14:25:48.373 INFO 3444 --- [ost-startStop-1] rmationExtractorJdbcDatabaseMetaDataImpl : HHH000262: Table not found: User
2018-12-11 14:25:49.213 INFO 3444 --- [ost-startStop-1] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'tenantdb-persistence-unit'
2018-12-11 14:25:49.273 INFO 3444 --- [ost-startStop-1] c.z.S.config.JerseyConfig : Register JAX-RS component -> com.zhtangsh.SpringDataMultiTenantMySQL.SipleEndpoint
2018-12-11 14:25:49.298 INFO 3444 --- [ost-startStop-1] c.z.S.config.JerseyConfig : Register JAX-RS component -> com.zhtangsh.SpringDataMultiTenantMySQL.config.NameFilter
2018-12-11 14:25:49.801 INFO 3444 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'characterEncodingFilter' to: [/*]
2018-12-11 14:25:49.802 INFO 3444 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'requestContextFilter' to: [/*]
2018-12-11 14:25:49.803 INFO 3444 --- [ost-startStop-1] o.s.b.w.servlet.ServletRegistrationBean : Mapping servlet: 'com.zhtangsh.SpringDataMultiTenantMySQL.config.JerseyConfig' to [/api/v1/*]
2018-12-11 14:25:50.513 INFO 3444 --- [ main] o.s.j.e.a.AnnotationMBeanExporter : Registering beans for JMX exposure on startup
2018-12-11 14:25:50.514 INFO 3444 --- [ main] o.s.j.e.a.AnnotationMBeanExporter : Bean with name 'masterDataSource' has been autodetected for JMX exposure
2018-12-11 14:25:50.521 INFO 3444 --- [ main] o.s.j.e.a.AnnotationMBeanExporter : Located MBean 'masterDataSource': registering with JMX server as MBean [com.zaxxer.hikari:name=masterDataSource,type=HikariDataSource]
2018-12-11 14:25:50.614 INFO 3444 --- [ main] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat started on port(s): 8800 (http)
2018-12-11 14:25:50.623 INFO 3444 --- [ main] .S.SpringDataMultiTenantMySqlApplication : Started SpringDataMultiTenantMySqlApplication in 13.463 seconds (JVM running for 14.398)
2018-12-11 14:26:54.394 INFO 3444 --- [nio-8800-exec-2] o.h.h.i.QueryTranslatorFactoryInitiator : HHH000397: Using ASTQueryTranslatorFactory
Hibernate:
select
currency0_.id as id1_1_,
currency0_.extras as extras2_1_,
currency0_.name as name3_1_
from
Currency currency0_
2018-12-11 14:26:54.398 INFO 3444 --- [nio-8800-exec-2] com.zaxxer.hikari.HikariDataSource : dd-connection-pool - Starting...
Tue Dec 11 14:26:54 CST 2018 WARN: Establishing SSL connection without server's identity verification is not recommended. According to MySQL 5.5.45+, 5.6.26+ and 5.7.6+ requirements SSL connection must be established by default if explicit option isn't set. For compliance with existing applications not using SSL the verifyServerCertificate property is set to 'false'. You need either to explicitly disable SSL by setting useSSL=false, or set useSSL=true and provide truststore for server certificate verification.
2018-12-11 14:26:54.483 INFO 3444 --- [nio-8800-exec-2] com.zaxxer.hikari.HikariDataSource : dd-connection-pool - Start completed.
2018-12-11 14:26:54.510 WARN 3444 --- [nio-8800-exec-2] o.h.engine.jdbc.spi.SqlExceptionHelper : SQL Error: 1146, SQLState: 42S02
2018-12-11 14:26:54.511 ERROR 3444 --- [nio-8800-exec-2] o.h.engine.jdbc.spi.SqlExceptionHelper : Table 'dd.Currency' doesn't exist
2018-12-11 14:26:54.545 ERROR 3444 --- [nio-8800-exec-2] o.a.c.c.C.[.[.[.[.z.S.c.JerseyConfig] : Servlet.service() for servlet [com.zhtangsh.SpringDataMultiTenantMySQL.config.JerseyConfig] in context with path [] threw exception [org.springframework.dao.InvalidDataAccessResourceUsageException: could not extract ResultSet; SQL [n/a]; nested exception is org.hibernate.exception.SQLGrammarException: could not extract ResultSet] with root cause
com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Table 'dd.Currency' doesn't exist
In master database, I setup two tenants as follows.
mysql> select * from master_tenant;
+----+----------+-----------+-------------------------------------+----------+---------+
| id | password | tenant_id | url | username | version |
+----+----------+-----------+-------------------------------------+----------+---------+
| 1 | root | cc | jdbc:mysql://10.19.140.200:3306/cc | root | 0 |
| 2 | root | dd | jdbc:mysql://10.19.140.200:3306/dd | root | 0 |
+----+----------+-----------+-------------------------------------+----------+---------+
2 rows in set (0.00 sec)
And all entities are initialized/update successfully in tenant cc, but failed in tenant dd.
mysql> use cc;
Database changed
mysql> show tables;
+--------------+
| Tables_in_cc |
+--------------+
| Company |
| Currency |
| User |
+--------------+
3 rows in set (0.00 sec)
mysql> use dd;
Database changed
mysql> show tables;
Empty set (0.00 sec)
Hello,
Thanks for sharing your project and it helps me lots on the solution for multitenancy.
But I was facing a runtime exception when trying to insert an object: no transaction is in progress. (When I set "allow_update_outside_transaction: true", it works )
Reading works fine.
After some google, I find a similar problem on stackoverflow, with his solution I can now do inserting within transaction.
https://stackoverflow.com/questions/58102106/jpa-hib-not-saving-to-database-but-reading-db-mysql-hikari-tomcat-9-spring
`
@Bean(name = "tenantTransactionManager")
public JpaTransactionManager transactionManager(
@Qualifier("tenantEntityManagerFactory") EntityManagerFactory tenantEntityManager) {
JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(tenantEntityManager);
return transactionManager;
}
`
My env: Java 8; Spring Boot 2.6.6; HikariCP 4.0.3 with MySQL 8.0 under MAC OSX
I hope it can help others to save time on this issue.
Regards,
Pai
User cannot be saved in database
Please provide sample sql scripts and user login information
i am not able to run the project. can you help ?
`org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'tenantEntityManagerFactory' defined in class path resource [com/sunitkatkar/blogspot/tenant/config/TenantDatabaseConfig.class]: Invocation of init method failed; nested exception is javax.persistence.PersistenceException: [PersistenceUnit: tenantdb-persistence-unit] Unable to build Hibernate SessionFactory; nested exception is java.lang.RuntimeException: Driver com.mysql.jdbc.Driver claims to not accept jdbcUrl, http://admin.localhost:8080
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1706) ~[spring-beans-5.0.6.RELEASE.jar:5.0.6.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:579) ~[spring-beans-5.0.6.RELEASE.jar:5.0.6.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:501) ~[spring-beans-5.0.6.RELEASE.jar:5.0.6.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:317) ~[spring-beans-5.0.6.RELEASE.jar:5.0.6.RELEASE]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:228) ~[spring-beans-5.0.6.RELEASE.jar:5.0.6.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:315) ~[spring-beans-5.0.6.RELEASE.jar:5.0.6.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199) ~[spring-beans-5.0.6.RELEASE.jar:5.0.6.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1089) ~[spring-context-5.0.6.RELEASE.jar:5.0.6.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:859) ~[spring-context-5.0.6.RELEASE.jar:5.0.6.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:550) ~[spring-context-5.0.6.RELEASE.jar:5.0.6.RELEASE]
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:140) ~[spring-boot-2.0.2.RELEASE.jar:2.0.2.RELEASE]
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:759) [spring-boot-2.0.2.RELEASE.jar:2.0.2.RELEASE]
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:395) [spring-boot-2.0.2.RELEASE.jar:2.0.2.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:327) [spring-boot-2.0.2.RELEASE.jar:2.0.2.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1255) [spring-boot-2.0.2.RELEASE.jar:2.0.2.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1243) [spring-boot-2.0.2.RELEASE.jar:2.0.2.RELEASE]
at com.sunitkatkar.blogspot.MultitenancyDynamicTenantApplication.main(MultitenancyDynamicTenantApplication.java:37) [classes/:na]
Caused by: javax.persistence.PersistenceException: [PersistenceUnit: tenantdb-persistence-unit] Unable to build Hibernate SessionFactory; nested exception is java.lang.RuntimeException: Driver com.mysql.jdbc.Driver claims to not accept jdbcUrl, http://admin.localhost:8080
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.buildNativeEntityManagerFactory(AbstractEntityManagerFactoryBean.java:402) ~[spring-orm-5.0.6.RELEASE.jar:5.0.6.RELEASE]
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:377) ~[spring-orm-5.0.6.RELEASE.jar:5.0.6.RELEASE]
at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.afterPropertiesSet(LocalContainerEntityManagerFactoryBean.java:341) ~[spring-orm-5.0.6.RELEASE.jar:5.0.6.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1765) ~[spring-beans-5.0.6.RELEASE.jar:5.0.6.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1702) ~[spring-beans-5.0.6.RELEASE.jar:5.0.6.RELEASE]
... 16 common frames omitted
Caused by: java.lang.RuntimeException: Driver com.mysql.jdbc.Driver claims to not accept jdbcUrl, http://admin.localhost:8080
at com.zaxxer.hikari.util.DriverDataSource.(DriverDataSource.java:106) ~[HikariCP-2.7.9.jar:na]
at com.zaxxer.hikari.pool.PoolBase.initializeDataSource(PoolBase.java:332) ~[HikariCP-2.7.9.jar:na]
at com.zaxxer.hikari.pool.PoolBase.(PoolBase.java:107) ~[HikariCP-2.7.9.jar:na]
at com.zaxxer.hikari.pool.HikariPool.(HikariPool.java:108) ~[HikariCP-2.7.9.jar:na]
at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:112) ~[HikariCP-2.7.9.jar:na]
at org.hibernate.engine.jdbc.connections.spi.AbstractDataSourceBasedMultiTenantConnectionProviderImpl.getAnyConnection(AbstractDataSourceBasedMultiTenantConnectionProviderImpl.java:25) ~[hibernate-core-5.2.17.Final.jar:5.2.17.Final]
at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator$MultiTenantConnectionProviderJdbcConnectionAccess.obtainConnection(JdbcEnvironmentInitiator.java:207) ~[hibernate-core-5.2.17.Final.jar:5.2.17.Final]
at org.hibernate.resource.transaction.backend.jdbc.internal.DdlTransactionIsolatorNonJtaImpl.getIsolatedConnection(DdlTransactionIsolatorNonJtaImpl.java:43) ~[hibernate-core-5.2.17.Final.jar:5.2.17.Final]
at org.hibernate.tool.schema.internal.exec.ImprovedExtractionContextImpl.getJdbcConnection(ImprovedExtractionContextImpl.java:60) ~[hibernate-core-5.2.17.Final.jar:5.2.17.Final]
at org.hibernate.tool.schema.internal.exec.ImprovedExtractionContextImpl.getJdbcDatabaseMetaData(ImprovedExtractionContextImpl.java:67) ~[hibernate-core-5.2.17.Final.jar:5.2.17.Final]
at org.hibernate.tool.schema.extract.internal.InformationExtractorJdbcDatabaseMetaDataImpl.getTables(InformationExtractorJdbcDatabaseMetaDataImpl.java:329) ~[hibernate-core-5.2.17.Final.jar:5.2.17.Final]
at org.hibernate.tool.schema.extract.internal.DatabaseInformationImpl.getTablesInformation(DatabaseInformationImpl.java:120) ~[hibernate-core-5.2.17.Final.jar:5.2.17.Final]
at org.hibernate.tool.schema.internal.GroupedSchemaMigratorImpl.performTablesMigration(GroupedSchemaMigratorImpl.java:65) ~[hibernate-core-5.2.17.Final.jar:5.2.17.Final]
at org.hibernate.tool.schema.internal.AbstractSchemaMigrator.performMigration(AbstractSchemaMigrator.java:207) ~[hibernate-core-5.2.17.Final.jar:5.2.17.Final]
at org.hibernate.tool.schema.internal.AbstractSchemaMigrator.doMigration(AbstractSchemaMigrator.java:114) ~[hibernate-core-5.2.17.Final.jar:5.2.17.Final]
at org.hibernate.tool.schema.spi.SchemaManagementToolCoordinator.performDatabaseAction(SchemaManagementToolCoordinator.java:183) ~[hibernate-core-5.2.17.Final.jar:5.2.17.Final]
at org.hibernate.tool.schema.spi.SchemaManagementToolCoordinator.process(SchemaManagementToolCoordinator.java:72) ~[hibernate-core-5.2.17.Final.jar:5.2.17.Final]
at org.hibernate.internal.SessionFactoryImpl.(SessionFactoryImpl.java:312) ~[hibernate-core-5.2.17.Final.jar:5.2.17.Final]
at org.hibernate.boot.internal.SessionFactoryBuilderImpl.build(SessionFactoryBuilderImpl.java:462) ~[hibernate-core-5.2.17.Final.jar:5.2.17.Final]
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:892) ~[hibernate-core-5.2.17.Final.jar:5.2.17.Final]
at org.springframework.orm.jpa.vendor.SpringHibernateJpaPersistenceProvider.createContainerEntityManagerFactory(SpringHibernateJpaPersistenceProvider.java:57) ~[spring-orm-5.0.6.RELEASE.jar:5.0.6.RELEASE]
at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:365) ~[spring-orm-5.0.6.RELEASE.jar:5.0.6.RELEASE]
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.buildNativeEntityManagerFactory(AbstractEntityManagerFactoryBean.java:390) ~[spring-orm-5.0.6.RELEASE.jar:5.0.6.RELEASE]
... 20 common frames omitted
Process finished with exit code 1
`
Using @id and @GeneratedValue(strategy = GenerationType.IDENTIY) user not saving in database works fine with AUTO
Hi Sunit,
Hope you are doing well.
While i was working in this project i found that when i was trying to add new tenant from Login Controller wherein i found that new user is not getting saved in databse.
Can you please check and get back to me if you can help.
@RequestMapping("/user/index")
public String userIndex(Model model) {
getLoggedInUsername().ifPresent(f -> {
model.addAttribute("userName", f);
});
getTenantName().ifPresent(d -> {
model.addAttribute("tenantName", d);
});
User user = new User();
user.setUsername("Shalu");
user.setTenant("tenant_5");
user.setPassword("hello");
user.setActive(true);
userService.save(user);
return "user/index";
}
Thank you:)
I am having issues with creating atomic operations in my Service classes. In my case I have a service that interacts with 2 repositories (both in the same tenant package) that I would like to wrap in a single transaction. If I add @Transactional
to any of my methods there, Spring throws the following error:
org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'org.springframework.transaction.PlatformTransactionManager' available: expected single matching bean but found 2: applicationTransactionManager,tenantTransactionManager
All my individual calls on the Repositories work fine, because they are bound to the correct Hibernate configuration:
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
entityManagerFactoryRef = "tenantEntityManagerFactory",
basePackages = { HibernateConstants.PACKAGE_REPOSITORY_TENANT },
transactionManagerRef = "tenantTransactionManager")
public class HibernateTenantConfig extends HibernateConfig {
...
}
It looks like Spring does not know which Transaction Manager to select in my Service classes, even though they are logically bound to either the tenant packages or application packages (you call them 'master').
How can I solve this? Preferably in a way where I don't have to explicitly mention the Transaction Manager on every single @Transactional
annotation.
i tried to download this project but when i try to boot from intellij i get this message
Hi, when i add a schema to the master_tenant table in my main database, it create a new master_tenant table in the customer tenant-database but i don't know why. i only should have one master_tenant in my main database?!
#BUG
***************************
APPLICATION FAILED TO START
***************************
Description:
Field productRepository in com.s.s.product.tenant.service.impl.ProductServiceImpl required a bean named 'tenantEntityManagerFactory' that could not be found.
The injection point has the following annotations:
- @org.springframework.beans.factory.annotation.Autowired(required=true)
The following candidates were found but could not be injected:
- Bean method 'entityManagerFactory' in 'TenantDatabaseConfig' not loaded because @ConditionalOnBean (names: datasourceBasedMultitenantConnectionProvider; SearchStrategy: all) did not find any beans named datasourceBasedMultitenantConnectionProvider
Action:
Consider revisiting the entries above or defining a bean named 'tenantEntityManagerFactory' in your configuration.
MacBook-Pro:~ s$ java -jar /Users/s/git/s-microservice/product-microservice/target/product-service-1.0.0-SNAPSHOT.jar
#FIX
// @Bean(name = "datasourceBasedMultitenantConnectionProvider")
// @ConditionalOnBean(name = "masterEntityManagerFactory")
// public MultiTenantConnectionProvider multiTenantConnectionProvider() {
// // Autowires the multi connection provider
// return new DataSourceBasedMultiTenantConnectionProviderImpl();
// }
@AutoConfigureAfter(name = "datasourceBasedMultitenantConnectionProvider")
public class TenantDatabaseConfig {
...
}
@Component("datasourceBasedMultitenantConnectionProvider")
public class DataSourceBasedMultiTenantConnectionProviderImpl
extends AbstractDataSourceBasedMultiTenantConnectionProviderImpl {
...
}
Problem in persisting tenant info in thread local
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.