多租户SaaS应用程序无法查找JNDI名称[java:comp / env / jdbc]

时间:2016-10-09 20:37:15

标签: spring hibernate jpa jndi tomcat8

在我的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

对此有何帮助?

先谢谢 Ĵ

0 个答案:

没有答案