我遇到Hibernate 5 / JPA的问题,我有问题需要解决。
我在Jboss EAP 6. +上部署我的应用程序,并在尝试构建EntityManagerFactory和MultitenatConnectionProvider时抛出异常
堆栈跟踪:
19:18:55,265 ERROR [org.jboss.msc.service.fail] (ServerService Thread Pool -- 49) MSC000001: Failed to start service jboss.persistenceunit."myProject.war#myDS": org.jboss.msc.service.StartException in service jboss.persistenceunit."myProject.war#myDS": javax.persistence.PersistenceException: [PersistenceUnit: myDS] Unable to build EntityManagerFactory
at org.jboss.as.jpa.service.PersistenceUnitServiceImpl$1.run(PersistenceUnitServiceImpl.java:103)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) [rt.jar:1.8.0_65]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) [rt.jar:1.8.0_65]
at java.lang.Thread.run(Thread.java:745) [rt.jar:1.8.0_65]
at org.jboss.threads.JBossThread.run(JBossThread.java:122) [jboss-threads-2.1.1.Final-redhat-1.jar:2.1.1.Final-redhat-1]
Caused by: javax.persistence.PersistenceException: [PersistenceUnit: myDS] Unable to build EntityManagerFactory
at org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:924)
at org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:899)
at org.hibernate.ejb.HibernatePersistence.createContainerEntityManagerFactory(HibernatePersistence.java:76)
at org.jboss.as.jpa.service.PersistenceUnitServiceImpl.createContainerEntityManagerFactory(PersistenceUnitServiceImpl.java:200)
at org.jboss.as.jpa.service.PersistenceUnitServiceImpl.access$600(PersistenceUnitServiceImpl.java:57)
at org.jboss.as.jpa.service.PersistenceUnitServiceImpl$1.run(PersistenceUnitServiceImpl.java:99)
... 4 more
Caused by: org.hibernate.service.spi.ServiceException: Unable to instantiate specified multi-tenant connection provider [com.multitenancyprovider.MultiTenantProvider]
at org.hibernate.service.jdbc.connections.internal.MultiTenantConnectionProviderInitiator.initiateService(MultiTenantConnectionProviderInitiator.java:97)
at org.hibernate.service.jdbc.connections.internal.MultiTenantConnectionProviderInitiator.initiateService(MultiTenantConnectionProviderInitiator.java:43)
at org.hibernate.service.internal.StandardServiceRegistryImpl.initiateService(StandardServiceRegistryImpl.java:79)
at org.hibernate.service.internal.AbstractServiceRegistryImpl.createService(AbstractServiceRegistryImpl.java:201)
at org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:175)
at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:156)
at org.hibernate.engine.jdbc.internal.JdbcServicesImpl.buildJdbcConnectionAccess(JdbcServicesImpl.java:228)
at org.hibernate.engine.jdbc.internal.JdbcServicesImpl.configure(JdbcServicesImpl.java:89)
at org.hibernate.service.internal.StandardServiceRegistryImpl.configureService(StandardServiceRegistryImpl.java:85)
at org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:184)
at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:156)
at org.hibernate.cfg.Configuration.buildTypeRegistrations(Configuration.java:1825)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1783)
at org.hibernate.ejb.EntityManagerFactoryImpl.<init>(EntityManagerFactoryImpl.java:96)
at org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:914)
... 9 more
的persistence.xml
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
<persistence-unit name="myDS" transaction-type="JTA">
<jta-data-source>java:/myDS</jta-data-source>
<class>com.general.entities.AccountingDocumentType</class>
<class>com.general.entities.AccountingOperation</class>
<properties>
<property name="hibernate.multiTenancy" value="SCHEMA"/>
<property name="hibernate.tenant_identifier_resolver" value="com.multitenancyprovider.SchemaResolver"/>
<property name="hibernate.multi_tenant_connection_provider" value="com.multitenancyprovider.MultiTenantProvider"/>
<property name="hibernate.show_sql" value="true" />
<property name="hibernate.format_sql" value="true" />
<property name="org.hibernate.type" value="debug" />
<property name="hibernate.cache.use_second_level_cache" value="true" />
<property name="hibernate.cache.use_query_cache" value="true" />
<property name="hibernate.cache.infinispan.statistics" value="false" />
<property name="hibernate.order_inserts" value="true"/>
<property name="hibernate.jdbc.batch_size" value="20"/>
<!-- Turn on entity and query cache statistics in the admin console -->
<property name="hibernate.generate_statistics" value="false" />
<!-- store entries in the cache in a more human friendly format - helps when interpreting logs -->
<property name="hibernate.cache.use_structured_entries" value="false" />
<!-- MultiTenancy -->
</properties>
</persistence-unit>
</persistence>
MultiTenantProvider.java
public class MultiTenantProvider implements MultiTenantConnectionProvider, ServiceRegistryAwareService {
private static final long serialVersionUID = 1L;
private DataSource dataSource;
public boolean supportsAggressiveRelease() {
return false;
}
public void injectServices(ServiceRegistryImplementor serviceRegistry) {
try {
final Context init = new InitialContext();
dataSource = (DataSource) init.lookup("java:/MyDS");
} catch (final NamingException e) {
throw new RuntimeException(e);
}
}
@SuppressWarnings("rawtypes")
public boolean isUnwrappableAs(Class clazz) {
return false;
}
public <T> T unwrap(Class<T> clazz) {
return null;
}
public Connection getAnyConnection() throws SQLException {
final Connection connection = dataSource.getConnection();
return connection;
}
public Connection getConnection(String tenantIdentifier) throws SQLException {
final Connection connection = getAnyConnection();
try {
connection.createStatement().execute("SET SCHEMA '" + tenantIdentifier + "'");
} catch (final SQLException e) {
throw new HibernateException("Could not alter JDBC connection to specified schema [" + tenantIdentifier + "]", e);
}
return connection;
}
public void releaseAnyConnection(Connection connection) throws SQLException {
try {
connection.createStatement().execute("SET SCHEMA 'public'");
} catch (final SQLException e) {
throw new HibernateException("Could not alter JDBC connection to specified schema [public]", e);
}
connection.close();
}
public void releaseConnection(String tenantIdentifier, Connection connection) throws SQLException {
releaseAnyConnection(connection);
}
}
standalone.xml / dataSource
<datasource jta="false" jndi-name="java:/MyDS" pool-name="MyDS" enabled="true" use-ccm="false">
<connection-url>jdbc:postgresql://localhost:5432/postgres</connection-url>
<driver-class>org.postgresql.Driver</driver-class>
<driver>postgresql-9.4.1209.jre6.jar</driver>
<security>
<user-name>postgres</user-name>
<password>cyberlink</password>
</security>
<validation>
<validate-on-match>false</validate-on-match>
<background-validation>false</background-validation>
</validation>
<timeout>
<set-tx-query-timeout>false</set-tx-query-timeout>
<blocking-timeout-millis>0</blocking-timeout-millis>
<idle-timeout-minutes>0</idle-timeout-minutes>
<query-timeout>0</query-timeout>
<use-try-lock>0</use-try-lock>
<allocation-retry>0</allocation-retry>
<allocation-retry-wait-millis>0</allocation-retry-wait-millis>
</timeout>
<statement>
<share-prepared-statements>false</share-prepared-statements>
</statement>
</datasource>
我在此页面上关注此示例并实现了Web上显示的测试项目:https://www.toptal.com/hibernate/build-multitenant-java-hibernate,当我想在个人项目中实现多租户时会出现此问题。