在我的spring4 JPA Hibernate 4 postgres数据库应用程序中,我为多租户SaaS数据库配置了OLTPdatasource。
在persistence.propertes中,我使用datasource作为多租户Master和OLTP数据库
persistence.properties
#Apache datasource config
dataSource.masterdb=java:comp/env/jdbc/masterDB
dataSource.oltpPrefix=java:comp/env/jdbc
dataSource.oltpAnyDataSource=1
在Persistence.config文件中,我的代码是
Persistence.config
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories
public class PersistentConfig
{
@Value ( "${hibernate.dialect}" )
private String dialect;
@Value ( "${hibernate.hbm2ddl.auto}" )
private String hbm2ddlAuto;
@Value ( "${hibernate.ejb.naming_strategy}" )
private String hibernateNamingStrategy;
@Value ( "${hibernate.ejb.connectionReleaseStrategy}" )
private String connectionReleaseStrategy;
@Value ( "${hibernate.show_sql}" )
private String showSql;
@Value ( "${hibernate.format_sql}" )
private String formatSql;
@Value ( "${dataSource.masterdb}" )
private String dataSourceMasterDB;
@Value ( "${dataSource.oltpPrefix}" )
private String dataSourcePrefix;
@Value ( "${dataSource.oltpAnyDataSource}" )
private String oltpAnyDataSource;
@Autowired
private MultitenantUtility identifierResolver;
@Bean ( name = "oltpEntityManager" )
public LocalContainerEntityManagerFactoryBean configureEntityManagerFactory ()
{
LocalContainerEntityManagerFactoryBean entityManagerFactoryBean = new LocalContainerEntityManagerFactoryBean ();
// entityManagerFactoryBean.setPackagesToScan ( "com.XXX.XXXX.datamodel.oltp" );
entityManagerFactoryBean.setPackagesToScan ( "com.XXX.XXXX.datamodel.oltp" );
entityManagerFactoryBean.setPersistenceProviderClass ( HibernatePersistenceProvider.class );
Properties jpaProterties = new Properties ();
jpaProterties.put ( Environment.DIALECT, dialect );
jpaProterties.put ( Environment.FORMAT_SQL, formatSql );
jpaProterties.put ( Environment.GENERATE_STATISTICS, true );
jpaProterties.put ( "hibernate.ejb.naming_strategy", hibernateNamingStrategy );
jpaProterties.put ( Environment.SHOW_SQL, showSql );
jpaProterties.put ( Environment.FORMAT_SQL, formatSql );
jpaProterties.put ( Environment.RELEASE_CONNECTIONS, connectionReleaseStrategy );
jpaProterties.put ( Environment.DIALECT, dialect );
jpaProterties.put ( Environment.MULTI_TENANT, "DATABASE" );
jpaProterties.put ( Environment.MULTI_TENANT_IDENTIFIER_RESOLVER, identifierResolver );
jpaProterties.put ( Environment.MULTI_TENANT_CONNECTION_PROVIDER, "org.hibernate.engine.jdbc.connections.spi.DataSourceBasedMultiTenantConnectionProviderImpl" );
jpaProterties.put ( Environment.DATASOURCE, dataSourcePrefix );
jpaProterties.put ( "hibernate.multi_tenant.datasource.identifier_for_any", oltpAnyDataSource );
entityManagerFactoryBean.setJpaProperties ( jpaProterties );
return entityManagerFactoryBean;
}
@Bean ( name = "masterDBEntityManger" )
public LocalContainerEntityManagerFactoryBean configureMasterDBEntityManagerFactory ()
{
LocalContainerEntityManagerFactoryBean entityManagerFactoryBean = new LocalContainerEntityManagerFactoryBean ();
entityManagerFactoryBean.setPackagesToScan ( "com.XXX.XXXX.datamodel.masterDB" );
entityManagerFactoryBean.setPersistenceProviderClass ( HibernatePersistenceProvider.class );
Properties jpaProterties = new Properties ();
jpaProterties.put ( Environment.DIALECT, dialect );
jpaProterties.put ( Environment.FORMAT_SQL, formatSql );
jpaProterties.put ( Environment.GENERATE_STATISTICS, true );
jpaProterties.put ( Environment.HBM2DDL_AUTO, hbm2ddlAuto );
jpaProterties.put ( "hibernate.ejb.naming_strategy", hibernateNamingStrategy );
jpaProterties.put ( Environment.SHOW_SQL, showSql );
jpaProterties.put ( Environment.FORMAT_SQL, formatSql );
jpaProterties.put ( Environment.RELEASE_CONNECTIONS, connectionReleaseStrategy );
jpaProterties.put ( Environment.DIALECT, dialect );
jpaProterties.put ( Environment.DATASOURCE, dataSourceMasterDB );
entityManagerFactoryBean.setJpaProperties ( jpaProterties );
return entityManagerFactoryBean;
}
@Bean ( name = "masterDBTransactionManager" )
public PlatformTransactionManager annotationMasterDBDrivenTransactionManager ()
{
JpaTransactionManager masterDBTransactionManager = new JpaTransactionManager ();
masterDBTransactionManager.setEntityManagerFactory ( configureMasterDBEntityManagerFactory ().getObject () );
return masterDBTransactionManager;
}
@Bean ( name = "oltpTransactionManager" )
public PlatformTransactionManager annotationDrivenTransactionManager ()
{
JpaTransactionManager oltpTransactionManager = new JpaTransactionManager ();
oltpTransactionManager.setEntityManagerFactory ( configureEntityManagerFactory ().getObject () );
return oltpTransactionManager;
}
}
我在Tomcat8 server.xml和context.xml中配置了数据库资源,如下所示
Tomcat8 Server.xml
<Resource name="java:comp/env/jdbc/masterDB"
global="java:comp/env/jdbc/masterDB"
auth="Container"
type="javax.sql.DataSource"
driverClassName="org.postgresql.Driver"
url="jdbc:postgresql://localhost:5432/Master_DB"
username="XXX"
password="XXX"
<Resource name="java:comp/env/jdbc/1"
global="java:comp/env/jdbc/1"
auth="Container"
type="javax.sql.DataSource"
driverClassName="org.postgresql.Driver"
url="jdbc:postgresql://localhost:5432/myApp"
username="XXX"
password="XXX"
Tomcat8 Context.xml
ResourceLink name="java:comp/env/jdbc/masterDB"
global="java:comp/env/jdbc/masterDB"
auth="Container"
type="javax.sql.DataSource" />
ResourceLink name="java:comp/env/jdbc/1"
global="java:comp/env/jdbc/1"
auth="Container"
type="javax.sql.DataSource" />
当我运行应用程序时,我收到了以下错误
Caused by: org.hibernate.engine.jndi.JndiException: Unable to lookup JNDI name [java:comp/env/jdbc]
at org.hibernate.engine.jndi.internal.JndiServiceImpl.locate(JndiServiceImpl.java:100)
at org.hibernate.engine.jdbc.connections.spi.DataSourceBasedMultiTenantConnectionProviderImpl.injectServices(DataSourceBasedMultiTenantConnectionProviderImpl.java:89)
at org.hibernate.service.internal.AbstractServiceRegistryImpl.injectDependencies(AbstractServiceRegistryImpl.java:255)
at org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:214)
at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:189)
at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator.buildJdbcConnectionAccess(JdbcEnvironmentInitiator.java:149)
at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator.initiateService(JdbcEnvironmentInitiator.java:66)
at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator.initiateService(JdbcEnvironmentInitiator.java:35)
at org.hibernate.boot.registry.internal.StandardServiceRegistryImpl.initiateService(StandardServiceRegistryImpl.java:88)
at org.hibernate.service.internal.AbstractServiceRegistryImpl.createService(AbstractServiceRegistryImpl.java:234)
... 86 more
Caused by: javax.naming.NameNotFoundException: Name [jdbc] is not bound in this Context. Unable to find [jdbc].
at org.apache.naming.NamingContext.lookup(NamingContext.java:818)
at org.apache.naming.NamingContext.lookup(NamingContext.java:152)
at org.apache.naming.NamingContext.lookup(NamingContext.java:829)
at org.apache.naming.NamingContext.lookup(NamingContext.java:152)
at org.apache.naming.NamingContext.lookup(NamingContext.java:829)
at org.apache.naming.NamingContext.lookup(NamingContext.java:152)
at org.apache.naming.SelectorContext.lookup(SelectorContext.java:134)
at javax.naming.InitialContext.lookup(InitialContext.java:421)
at org.hibernate.engine.jndi.internal.JndiServiceImpl.locate(JndiServiceImpl.java:97)
... 95 more
对此有何帮助?
先谢谢 Ĵ