hibernate - 在 Hibernete 多租户环境中,persist() 后无法获取实体 ID
问题描述
在调用实体管理器的persist() 后,我试图获取实体的ID。但是,在调用 persist() 之后,我没有得到 ID。em.refresh() 也失败了。我正在使用 Hibernate 的数据库多租户。在我介绍多租户之前,这一切都很好。
这就是我所拥有的:
public class MyEntity{
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Basic(optional = false)
@Column(name = "ID")
.....
}
@Stateless
public class ActionDAO{
......
@PersistenceContext(unitName = "project-persistence-unit")
protected EntityManager em;
public void saveEntity(MyEntity q) {
if (q.getId() == null) {
em.persist(q);
System.out.println(q.getID); // expect to get an ID here but i get 0 .
} else {
em.merge(q);
}
}
}
我已经四处寻找,但找不到解决方案!
多租户类如下:
public class CurrentTenantIdentifierResolverImpl implements CurrentTenantIdentifierResolver {
@Override
public String resolveCurrentTenantIdentifier() {
String tenant = ThreadState.INSTANCE.getTenantId();
return tenant;
}
@Override
public boolean validateExistingCurrentSessions() {
return true;
}
}
public class MultiTenantConnectionProviderImpl extends AbstractMultiTenantConnectionProvider {
@Override
protected ConnectionProvider getAnyConnectionProvider() {
Properties properties = new Properties();
DriverManagerDataSource ds = new DriverManagerDataSource();
ds.setUrl("jdbc:mysql://localhost:8889/project1?serverTimezone=UTC");
ds.setUsername("root");
ds.setPassword("root");
DatasourceConnectionProviderImpl d = new DatasourceConnectionProviderImpl();
d.setDataSource(ds);
d.configure(properties);
return (ConnectionProvider) d;
}
@Override
protected ConnectionProvider selectConnectionProvider(String tenantId) {
Properties properties = new Properties();
String path = MyConstants.DOCUMENT_ROOT + "/" + tenantId.toUpperCase();
File file = new File(path + File.separator + "DATABASE.properties");
if (file.exists()) {
Properties prop = new Properties();
try {
InputStream input = new FileInputStream(path + "/DATABASE.properties");
prop.load(input);
DriverManagerDataSource ds = new DriverManagerDataSource();
ds.setUrl(prop.getProperty("URL"));
ds.setUsername(prop.getProperty("USERNAME"));
ds.setPassword(prop.getProperty("PASSWORD"));
input.close();
DatasourceConnectionProviderImpl d = new DatasourceConnectionProviderImpl();
d.setDataSource(ds);
d.configure(properties);
return (ConnectionProvider) d;
} catch (IOException | NullPointerException ex) {
Logger.getLogger(MultiTenantConnectionProviderImpl.class.getName()).log(Level.SEVERE, null, ex);
ex.printStackTrace();
}
}
return null;
}
}
持久性.xml
<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="project-persistence-unit" transaction-type="JTA">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<!--<jta-data-source>java:/PROJECT-DS</jta-data-source>-->
<properties>
<property name="hibernate.jdbc.time_zone" value="UTC"/>
<property name="hibernate.archive.autodetection" value="class"/>
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5Dialect"/>
<property name="hibernate.jdbc.batch_size" value="250"/>
<property name="hibernate.jdbc.fetch_size" value="500"/>
<property name="hibernate.order_inserts" value="true"/>
<property name="hibernate.order_updates" value="true"/>
<property name="jboss.entity.manager.jndi.name" value="java:/myprojectEM"/>
<property name="jboss.entity.manager.factory.jndi.name" value="java:/myprojectEMF"/>
<property name="hibernate.generate_statistics" value="false"/>
<property name="hibernate.multi_tenant_connection_provider" value="com.myproject.auxiliary.MultiTenantConnectionProviderImpl"/>
<property name="hibernate.tenant_identifier_resolver" value="com.myproject.auxiliary.CurrentTenantIdentifierResolverImpl"/>
<property name="hibernate.multiTenancy" value="DATABASE"/>
<property name="hibernate.enable_lazy_load_no_trans" value="true"/>
</properties>
</persistence-unit>
</persistence>
解决方案
Update class MultiTenantConnectionProviderImpl to use org.apache.commons.dbcp.BasicDataSource instead of org.hibernate.engine.jdbc.connections.internal.DatasourceConnectionProviderImpl