java—在一个简单的多租户应用程序中将hibernate从5.3降级到4.3.10时出现问题

scyqe7ek  于 2021-07-09  发布在  Java
关注(0)|答案(0)|浏览(225)

我一直在做一个poc来制作一个简单的java+hibernate多租户应用程序(数据库方法),我成功地运行了它,没有任何错误。下面是我用来制作的jar。

现在的问题是,我们必须在这个poc中将hibernate版本降级到4.x,以便我们的老项目可以利用它。
所以,我在下面的截图中把jar改成这样

更改jar版本并运行driverclass.java后,控制台中显示的错误消息如下:

Apr 21, 2021 12:30:02 PM org.hibernate.engine.jdbc.connections.internal.MultiTenantConnectionProviderInitiator initiateService
WARN: Unable to locate specified class [
            MultiTenantConnectionProviderImpl
        ]
org.hibernate.boot.registry.classloading.spi.ClassLoadingException: Unable to load class [
            MultiTenantConnectionProviderImpl
        ]
    at org.hibernate.boot.registry.classloading.internal.ClassLoaderServiceImpl.classForName(ClassLoaderServiceImpl.java:245)
    at org.hibernate.engine.jdbc.connections.internal.MultiTenantConnectionProviderInitiator.initiateService(MultiTenantConnectionProviderInitiator.java:91)
    at org.hibernate.engine.jdbc.connections.internal.MultiTenantConnectionProviderInitiator.initiateService(MultiTenantConnectionProviderInitiator.java:45)
    at org.hibernate.boot.registry.internal.StandardServiceRegistryImpl.initiateService(StandardServiceRegistryImpl.java:105)
    at org.hibernate.service.internal.AbstractServiceRegistryImpl.createService(AbstractServiceRegistryImpl.java:251)
    at org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:225)
    at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:206)
    at org.hibernate.engine.jdbc.internal.JdbcServicesImpl.buildJdbcConnectionAccess(JdbcServicesImpl.java:265)
    at org.hibernate.engine.jdbc.internal.JdbcServicesImpl.configure(JdbcServicesImpl.java:94)
    at org.hibernate.boot.registry.internal.StandardServiceRegistryImpl.configureService(StandardServiceRegistryImpl.java:111)
    at org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:234)
    at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:206)
    at org.hibernate.cfg.Configuration.buildTypeRegistrations(Configuration.java:1887)
    at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1845)
    at HibernateUtil.build(HibernateUtil.java:19)
    at HibernateUtil.<clinit>(HibernateUtil.java:8)
    at DriverClass.printEmployeeDetailsFrom(DriverClass.java:30)
    at DriverClass.main(DriverClass.java:16)
Caused by: java.lang.ClassNotFoundException: Could not load requested class : 
            MultiTenantConnectionProviderImpl

    at org.hibernate.boot.registry.classloading.internal.ClassLoaderServiceImpl$AggregatedClassLoader.findClass(ClassLoaderServiceImpl.java:230)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
    at java.lang.Class.forName0(Native Method)
    at java.lang.Class.forName(Class.java:348)
    at org.hibernate.boot.registry.classloading.internal.ClassLoaderServiceImpl.classForName(ClassLoaderServiceImpl.java:242)
    ... 17 more

Exception in thread "main" java.lang.ExceptionInInitializerError
    at DriverClass.printEmployeeDetailsFrom(DriverClass.java:30)
    at DriverClass.main(DriverClass.java:16)
Caused by: org.hibernate.service.spi.ServiceException: Unable to locate specified multi-tenant connection provider [
            MultiTenantConnectionProviderImpl
        ]
    at org.hibernate.engine.jdbc.connections.internal.MultiTenantConnectionProviderInitiator.initiateService(MultiTenantConnectionProviderInitiator.java:95)
    at org.hibernate.engine.jdbc.connections.internal.MultiTenantConnectionProviderInitiator.initiateService(MultiTenantConnectionProviderInitiator.java:45)
    at org.hibernate.boot.registry.internal.StandardServiceRegistryImpl.initiateService(StandardServiceRegistryImpl.java:105)
    at org.hibernate.service.internal.AbstractServiceRegistryImpl.createService(AbstractServiceRegistryImpl.java:251)
    at org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:225)
    at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:206)
    at org.hibernate.engine.jdbc.internal.JdbcServicesImpl.buildJdbcConnectionAccess(JdbcServicesImpl.java:265)
    at org.hibernate.engine.jdbc.internal.JdbcServicesImpl.configure(JdbcServicesImpl.java:94)
    at org.hibernate.boot.registry.internal.StandardServiceRegistryImpl.configureService(StandardServiceRegistryImpl.java:111)
    at org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:234)
    at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:206)
    at org.hibernate.cfg.Configuration.buildTypeRegistrations(Configuration.java:1887)
    at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1845)
    at HibernateUtil.build(HibernateUtil.java:19)
    at HibernateUtil.<clinit>(HibernateUtil.java:8)
    ... 2 more

任何帮助或建议都将不胜感激。。。。!提前谢谢。。!
以下是驱动poc的文件:
驱动程序类.java

import java.util.List;

import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import com.baji.pojo.EmployeeDetails;

public class DriverClass {
    public static void main(String[] args) {    
        System.out.println("\n\nEmployees from  DB_For_HibernatePOC DB:-\n");
        printEmployeeDetailsFrom("DB_For_HibernatePOC");
        System.out.println("\n\nEmployees from DB_For_HibernatePOC_Client1 DB :-\n");
        printEmployeeDetailsFrom("DB_For_HibernatePOC_Client1");

//      System.out.println("Saving Employees to new DB for Client 01");
//      saveEmployeeDetails("DB_For_HibernatePOC_Client1");

    }

    /*
     * this method is to print Employee Details
     * from the specified database 
     */
    static void printEmployeeDetailsFrom(String tenant) {
        SessionFactory factory = HibernateUtil.factory();
        Session session1 = factory.withOptions().tenantIdentifier(tenant).openSession();

        String hqlQuery = "from EmployeeDetails employeeDetails";
        Query query = session1.createQuery(hqlQuery);

        @SuppressWarnings("unchecked")
        List<EmployeeDetails> employees = (List<EmployeeDetails>) query.list();

        for (EmployeeDetails e : employees) {
            System.out.println(e.toString());
        }
        session1.close();
//      factory.close();
    }

    /*
     * This method is to save Employee Details
     * into specified Database
     */
    static void saveEmployeeDetails(String tenant) {
        SessionFactory factory = HibernateUtil.factory();
        Session session1 = factory.withOptions().tenantIdentifier(tenant).openSession();
        Transaction t = session1.beginTransaction();
        EmployeeDetails emp = new EmployeeDetails();
//      emp.setId(1);
        emp.setFirstName("Diana ");
        emp.setLastName("Prince");
        session1.save(emp);
        t.commit();
        System.out.println("successfully saved");
        session1.close();
//      factory.close();
    }
}

hibernateutil.java版本

import org.hibernate.SessionFactory;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cfg.Configuration;
/*
 * This class is to get Session Factory
 */
public class HibernateUtil {
    private static SessionFactory factory = build();

    private static SessionFactory build() {
        Configuration configuration1 = new Configuration();
        configuration1.configure();

        StandardServiceRegistryBuilder builder = new StandardServiceRegistryBuilder().configure("hibernate.cfg.xml");
        SessionFactory sessionFactory = configuration1.buildSessionFactory(builder.build());
        return sessionFactory;

    }

    public static SessionFactory factory() {
        return factory;
    }
}

multitenantconnectionproviderimpl.java

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

import org.hibernate.HibernateException;
import org.hibernate.engine.config.spi.ConfigurationService;
import org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl;
import org.hibernate.engine.jdbc.connections.spi.MultiTenantConnectionProvider;
import org.hibernate.service.spi.ServiceRegistryAwareService;
import org.hibernate.service.spi.ServiceRegistryImplementor;

public class MultiTenantConnectionProviderImpl implements MultiTenantConnectionProvider, ServiceRegistryAwareService {

    /**
     * 
     */
    private static final long serialVersionUID = 1L;

    private DriverManagerConnectionProviderImpl provider = new DriverManagerConnectionProviderImpl();

    public boolean isUnwrappableAs(Class arg0) {
        return provider.isUnwrappableAs(arg0);
    }

    public <T> T unwrap(Class<T> arg0) {
        return provider.unwrap(arg0);
    }

    @Override
    public Connection getAnyConnection() throws SQLException {
        return provider.getConnection();
    }

    @Override
    public Connection getConnection(String tenantId) throws SQLException {

        Connection con = getAnyConnection();
        try {
            System.out.println("Using " + tenantId + " as database");
            con.createStatement().execute("USE " + tenantId);

        } catch (SQLException ex) {
            System.out.println("Using " + tenantId + " as database");
            throw new HibernateException("Could not alter connection for specific schema");
        }
        return con;
    }

    public void releaseAnyConnection(Connection con) throws SQLException {
        provider.closeConnection(con);

    }

    @Override
    public void releaseConnection(String tenantId, Connection con) throws SQLException {
        try {
            con.createStatement().execute("USE " + tenantId);
            System.out.println("Now, released " + tenantId);
        } catch (SQLException ex) {
            throw new HibernateException("Unable to reset");
        }
        provider.closeConnection(con);

    }

    public boolean supportsAggressiveRelease() {
        return false;
    }

    public void injectServices(ServiceRegistryImplementor registry) {
        Map settings = registry.getService(ConfigurationService.class).getSettings();
        provider.configure(settings);
        provider.injectServices(registry);

    }
}

休眠.cfg.xml

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

<hibernate-configuration>

    <session-factory>
        <property name="hbm2ddl.auto">update</property>
        <property name="dialect">org.hibernate.dialect.SQLServer2012Dialect</property>
        <property name="connection.url">jdbc:sqlserver://localhost;</property>
        <property name="connection.username">systemadmin</property>
        <property name="connection.password">systemadmin</property>
        <property name="show_sql">true</property>

        <property name="connection.driver_class">com.microsoft.sqlserver.jdbc.SQLServerDriver</property>

        <!-- multi-tenancy configuration -->
    <property name="hibernate.multiTenancy">DATABASE</property>
        <property name="hibernate.multi_tenant_connection_provider">
            MultiTenantConnectionProviderImpl
        </property>

        <!-- HBM configuration -->

        <!--<mapping file="com/baji/mappings/EmployeeDetails.hbm.xml" />-->

        <mapping class="com.baji.pojo.EmployeeDetails"/>
    </session-factory>

</hibernate-configuration>

暂无答案!

目前还没有任何答案,快来回答吧!

相关问题