我一直在做一个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>
暂无答案!
目前还没有任何答案,快来回答吧!