2 jingwen1598 jingwen1598 于 2016.04.01 07:35 提问

求大神解答 hibernate Multi-tenancy多租户connection空指针? 5C

hibernate Multi-tenancy多租户为什么connection总是空指针?

运行错误详情
 Exception in thread "main" java.lang.NullPointerException
    at org.hibernate.c3p0.internal.C3P0ConnectionProvider.getConnection(C3P0ConnectionProvider.java:73)
    at com.qzd.hibernate.MultiTenantConnectionProviderImpl.getAnyConnection(MultiTenantConnectionProviderImpl.java:65)
    at com.qzd.hibernate.MultiTenantConnectionProviderImpl.getConnection(MultiTenantConnectionProviderImpl.java:78)
    at org.hibernate.internal.AbstractSessionImpl$ContextualJdbcConnectionAccess.obtainConnection(AbstractSessionImpl.java:429)
    at org.hibernate.resource.jdbc.internal.LogicalConnectionManagedImpl.acquireConnectionIfNeeded(LogicalConnectionManagedImpl.java:84)
    at org.hibernate.resource.jdbc.internal.LogicalConnectionManagedImpl.getPhysicalConnection(LogicalConnectionManagedImpl.java:109)
    at org.hibernate.resource.jdbc.internal.LogicalConnectionManagedImpl.getConnectionForTransactionManagement(LogicalConnectionManagedImpl.java:227)
    at org.hibernate.resource.jdbc.internal.LogicalConnectionManagedImpl.begin(LogicalConnectionManagedImpl.java:234)
    at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl$TransactionDriverControlImpl.begin(JdbcResourceLocalTransactionCoordinatorImpl.java:214)
    at org.hibernate.engine.transaction.internal.TransactionImpl.begin(TransactionImpl.java:52)
    at org.hibernate.internal.SessionImpl.beginTransaction(SessionImpl.java:1525)
    at com.qzd.hibernate.TestMultiTenancy.main(TestMultiTenancy.java:40)

hibernate.cfg.xml配置
 <?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
    "-//Hibernate/Hibernate Configuration DTD//EN"
    "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">

<hibernate-configuration>
<session-factory>
    <property name="hibernate.cache.use_query_cache">true</property>
    <property name="hibernate.cache.use_second_level_cache">true</property>
    <property name="hibernate.cache.use_structured_entries">true</property>
   <property name="hibernate.cache.region.factory_class">org.hibernate.cache.EhCacheRegionFactory</property>    

    <property name="net.sf.ehcache.configurationResourceName">ehcache.xml</property>  

    <property name="hibernate.connection.provider_class">
        org.hibernate.c3p0.internal.C3P0ConnectionProvider
    </property>
    <property name="hibernate.connection.driver_class">
        com.mysql.jdbc.Driver
    </property>
    <property name="hibernate.connection.url">
        jdbc:mysql://localhost:3306/hibernate
    </property>
    <property name="hibernate.connection.username">root</property>
    <property name="hibernate.connection.password">
        ,an.123;kun
    </property>

    <property name="hibernate.c3p0.min_size">3</property>
    <property name="hibernate.c3p0.max_size">10</property>
    <property name="hibernate.c3p0.timeout">1500</property>
    <property name="hibernate.dialect">
        org.hibernate.dialect.MySQL5Dialect
    </property>

    <property name="show_sql">true</property>
    <property name="format_sql">true</property> 

    <property name="myeclipse.connection.profile">mysql</property>
    <property name="connection.url">
        jdbc:mysql://localhost:3306/hibernate
    </property>
    <property name="connection.username">root</property>
    <property name="connection.password">,an.123;kun</property>
    <property name="connection.driver_class">
        com.mysql.jdbc.Driver
    </property>
    <property name="dialect">
        org.hibernate.dialect.MySQLDialect
    </property>


    <property name="hibernate.multiTenancy">shema</property> 
    <property name="hibernate.multi_tenant_connection_provider">com.qzd.hibernate.MultiTenantConnectionProviderImpl</property> 


    <mapping resource="com/qzd/hibernate/People.hbm.xml" />
    <mapping resource="com/qzd/hibernate/Wife.hbm.xml" />
    <mapping resource="com/qzd/hibernate/Child.hbm.xml" />

    <mapping resource="com/qzd/hibernate/Address.hbm.xml" />
    <mapping resource="com/qzd/hibernate/Person.hbm.xml" />

    <mapping resource="com/qzd/hibernate/Tempbook.hbm.xml" />
    <mapping resource="com/qzd/hibernate/Tempkind.hbm.xml" />
</session-factory>
</hibernate-configuration>
package com.qzd.hibernate;

import java.sql.Connection;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

import javax.sql.DataSource;

import org.apache.commons.dbcp2.BasicDataSource;
import org.hibernate.HibernateException;
import org.hibernate.c3p0.internal.C3P0ConnectionProvider;
import org.hibernate.engine.jdbc.connections.internal.DatasourceConnectionProviderImpl;
import org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl;
import org.hibernate.engine.jdbc.connections.spi.ConnectionProvider;
import org.hibernate.engine.jdbc.connections.spi.MultiTenantConnectionProvider;
import org.hibernate.service.spi.Configurable;
import org.hibernate.service.spi.ServiceRegistryAwareService;
import org.hibernate.service.spi.ServiceRegistryImplementor;
import org.hibernate.service.spi.Stoppable;
import org.springframework.jdbc.datasource.DriverManagerDataSource;

public class MultiTenantConnectionProviderImpl implements MultiTenantConnectionProvider,Configurable,Stoppable,ServiceRegistryAwareService{
    private C3P0ConnectionProvider connectionProvider=new C3P0ConnectionProvider();

    @Override
    public boolean isUnwrappableAs(Class arg0) {
        // TODO Auto-generated method stub
        return false;
    }

    @Override
    public <T> T unwrap(Class<T> arg0) {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public void stop() {
        // TODO Auto-generated method stub

    }

    @Override
    public Connection getAnyConnection() throws SQLException {
        Connection conn = null;

        try {
            conn = connectionProvider.getConnection();
        } catch (SQLException e) {
            throw new SQLException(e);
        } finally {
            System.out.println("222222222222222222888888888::" + (conn == null));
        }       

        return connectionProvider.getConnection();
    }

    @Override
    public Connection getConnection(String tenantIdentifier) throws SQLException {
        final Connection connection = getAnyConnection();
        try {
            connection.createStatement().execute( "USE " + tenantIdentifier );
        }
        catch ( SQLException exception ) {
            throw new HibernateException(
                    "Could not alter JDBC connection to specified schema [" +tenantIdentifier + "]",
                    exception
            );
        }
        return connection;
    }

    @Override
    public void releaseAnyConnection(Connection connection) throws SQLException {
        connectionProvider.closeConnection(connection);
    }

    @Override
    public void releaseConnection(String tenantIdentifier, Connection connection)throws SQLException {
        try {
            connection.createStatement().execute( "USE antest" );
        }
        catch ( SQLException exception) {
            throw new HibernateException(
                    "Could not alter JDBC connection to specified schema [" +
                            tenantIdentifier + "]",
                    exception
            );
        }
        connectionProvider.closeConnection( connection );
    }

    @Override
    public boolean supportsAggressiveRelease() {
        // TODO Auto-generated method stub
        return false;
    }

    @Override
    public void configure(Map props) {
        Properties c3props = new Properties();
        Map allProps = new HashMap();
        allProps.putAll( props );
        allProps.putAll( c3props );
    }

    @Override
    public void injectServices(ServiceRegistryImplementor arg0) {
        // TODO Auto-generated method stub

    }
} 
 测试文件代码
 package com.qzd.hibernate;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.boot.registry.StandardServiceRegistry;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cfg.Configuration;
import org.hibernate.cfg.Environment;
import org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl;
import org.hibernate.envers.AuditReader;
import org.hibernate.envers.AuditReaderFactory;
import org.hibernate.envers.query.AuditEntity;
import org.hibernate.envers.query.AuditQuery;

import com.qzd.shop.web.bean.Book;

public class TestMultiTenancy {
    public static void main(String args[]) {
        Configuration config = new Configuration();

        StandardServiceRegistryBuilder standardRegistryBuilder = new StandardServiceRegistryBuilder();
        standardRegistryBuilder.configure("hibernate.cfg.xml").applySetting(
                "hibernate.multiTenancy",
                org.hibernate.MultiTenancyStrategy.SCHEMA);
        StandardServiceRegistry standardRegistry = standardRegistryBuilder
                .build();

        SessionFactory sessionFactory = config
                .buildSessionFactory(standardRegistry);

        Session session = sessionFactory.withOptions()
                .tenantIdentifier("hibernate").openSession();
        Transaction trans = session.beginTransaction();

        try {
            Query query=session.createQuery("select new list(book.bookName,book.author,book.price) from Book book where book.bookId=3");
            query.list().forEach((c)->System.out.println(c));
            trans.commit();
        } catch (Exception ex) {
            try {
                trans.rollback();
            } catch (HibernateException e) {
                System.out.print(e.getMessage());
            }
            System.out.println(ex.getMessage());
        } finally {
            session.close();
            sessionFactory.close();
        }
    }
}

求大神解答,不胜感激。

1个回答

xy_focus
xy_focus   2016.04.01 17:43

c3p0报错

 <?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
    http://www.springframework.org/schema/tx  http://www.springframework.org/schema/tx/spring-tx-2.0.xsd
    http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd">


<!-- 配置属性文件位置 -->
<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
    <property name="location" value="classpath:jdbc.properties"/>
  </bean>
  <!-- 连接池配置 -->
  <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
    <property name="driverClass" value="${jdbc.driver}" />
    <property name="jdbcUrl" value="${jdbc.url}" />
    <property name="user" value="${jdbc.username}" />
    <property name="password" value="${jdbc.password}" />
    <property name="autoCommitOnClose" value="true" />
    <property name="checkoutTimeout" value="${cpool.checkoutTimeout}" />
    <property name="initialPoolSize" value="${cpool.minPoolSize}" />
    <property name="minPoolSize" value="${cpool.minPoolSize}" />
    <property name="maxPoolSize" value="${cpool.maxPoolSize}" />
    <property name="maxIdleTime" value="${cpool.maxIdleTime}" />
    <property name="acquireIncrement" value="${cpool.acquireIncrement}" />
    <property name="maxIdleTimeExcessConnections" value="${cpool.maxIdleTimeExcessConnections}" />
  </bean> 

    <bean id="sessionFactory"
        class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
        <property name="dataSource">
            <ref bean="dataSource" />
        </property>
        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.dialect">
                    org.hibernate.dialect.Oracle9Dialect
                </prop>
                <prop key="hibernate.show_sql">true</prop>
                <prop key="hibernate.sql_format">true</prop>
            </props>
        </property>
        <property name="mappingResources">
            <list>
                <value></value>
            </list>
        </property>
    </bean>
<!-- 事务配置 -->

<!--Step1.事务管理器配置-->
    <bean id="txManager"
        class="org.springframework.orm.hibernate3.HibernateTransactionManager">
        <property name="sessionFactory" ref="sessionFactory" />
    </bean>

 <!--Step2.交给SPRING事务管理的一些方法.-->
    <aop:config>
        <!-- 指定切面是哪个范围类,比如你项目的SERVICE的所有方法-->
        <aop:pointcut id="serviceMethods" expression="execution(* service..*.*(..))" />
        <!-- 一个通知的集合,这个集合都用上的POINTCUT-->
        <aop:advisor advice-ref="txAdvice" pointcut-ref="serviceMethods" />
    </aop:config>

<!--定义通知集合,以TX开头,是有事务的 -->
    <tx:advice id="txAdvice" transaction-manager="txManager">
        <tx:attributes>
            <!--
                所有的以ADD开头的方法名的方法都用事务 REQUIRED
                表示,比如方法A有更新操作,A中调用了B方法,那么B到底是重新起一个事务还是用A方法的事务,
                REQUIRED标识不起就用当前事务,如果有就用A的,如果没有就起一个
            -->
            <tx:method name="add*" propagation="REQUIRED" />
            <tx:method name="delete*" propagation="REQUIRED" />
            <tx:method name="del*" propagation="REQUIRED" />
            <tx:method name="update*" propagation="REQUIRED" />
            <!--
                加入只读,说明以GET或者LOAD开头的方法名的方法都是只读事务,说明这个
                方法内没有UPDATE操作,这样声明一下可以提高该查询方法的效率
            -->
            <tx:method name="get*" propagation="REQUIRED" read-only="true" />
            <tx:method name="load*" propagation="REQUIRED" read-only="true" />
            <tx:method name="query*" propagation="REQUIRED" read-only="true" />
        </tx:attributes>
    </tx:advice>
</beans>
 #mysql
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/b2c
jdbc.username=root
jdbc.password=


#ms sql
#jdbc.driver=com.microsoft.sqlserver.jdbc.SQLServerDriver

#jdbc.url=jdbc:sqlserver://localhost:1433;database=hibernate
#jdbc.username=sa
#jdbc.password=sa

#oracle
jdbc.url=jdbc:oracle:thin:@127.0.0.1:1521:orcl
jdbc.driver=oracle.jdbc.driver.OracleDriver
jdbc.username=scott
jdbc.password=tiger

cpool.checkoutTimeout=25000
cpool.minPoolSize=1
cpool.maxPoolSize=5
cpool.maxIdleTime=25200
cpool.maxIdleTimeExcessConnections=1800
cpool.acquireIncrement=5

你参考下,

Csdn user default icon
上传中...
上传图片
插入图片
准确详细的回答,更有利于被提问者采纳,从而获得C币。复制、灌水、广告等回答会被删除,是时候展现真正的技术了!