【发布时间】:2022-01-17 22:47:54
【问题描述】:
我在尝试使用 Netbeans 在 JPA 应用程序中实现多租户休眠时遇到问题。问题是de方法getEntityManager(String multitenancyIdentifier)本身没有执行代码,参数的值为null,所以没有改变架构。
为了实现多租户,我必须包含这 3 个类:
SchemaMultiTenantProvider.java
SchemaTenantResolver.java
MuiltitenancyResolver.java
您可以在此链接上找到此示例: https://developers.redhat.com/blog/2020/11/12/jakarta-ee-multitenancy-with-jpa-on-wildfly-part-2#
在 SchemaMultiTenantProvider 中,我们有一行来更改架构:
connection.createStatement().execute("SET SCHEMA '" + tenantIdentifier + "'");
在 SchemaTenantResolver 中,我们有一个 Map 来选择参考将登录到应用程序的用户的架构:
public SchemaTenantResolver(){
userDatasourceMap = new HashMap();
userDatasourceMap.put("default", "public");
userDatasourceMap.put("usuario1", "prueba");
}
而MuiltitenancyResolver我们设置了tenantIdentifier,设置在getEntityManager(String multitenancyIdentifier)中:
public void setTenantIdentifier(String tenantIdentifier) {
this.tenantIdentifier = tenantIdentifier;
}
在持久性中我有这个:
< provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
< jta-data-source>jdbc/dspw</jta-data-source>
< exclude-unlisted-classes>false</exclude-unlisted-classes>
< properties>
< property name="javax.persistence.schema-generation.database.action" value="none"/>
< property name="hibernate.dialect" value="org.hibernate.dialect.PostgresPlusDialect"/>
< property name="hibernate.multiTenancy" value="SCHEMA"/>
< property name="hibernate.tenant_identifier_resolver" value="services.SchemaTenantResolver"/>
< property name="hibernate.multi_tenant_connection_provider" value="services.SchemaMultiTenantProvider"/>
</ properties>
在我的 AbstractFacade 我有这个:
public abstract class AbstractFacade<T> {
private Class<T> entityClass;
@PersistenceUnit
protected EntityManagerFactory emf;
public AbstractFacade(Class<T> entityClass) {
this.entityClass = entityClass;
}
public EntityManager getEntityManager(String multitenancyIdentifier){
System.out.println("id getEntityManager: " + multitenancyIdentifier);
final SessionFactoryImplementor sfi = emf.unwrap(SessionFactoryImplementor.class);
final MuiltitenancyResolver tenantResolver = (MuiltitenancyResolver) sfi.getCurrentTenantIdentifierResolver();
tenantResolver.setTenantIdentifier(multitenancyIdentifier);
return emf.createEntityManager();
}
在同一个类中,我有这个方法可以找到任何 db 对象:
public T find(Object id, String multitenancyIdentifier) {
System.out.println("id find: " + multitenancyIdentifier);
return getEntityManager(multitenancyIdentifier).find(entityClass, id);
}
在 Facades 类之一中(例如)我有这个:
public class UsuarioFacade extends AbstractFacade<Usuario> {
@PersistenceContext(unitName = "SPWPersistence")
private EntityManager em;
@Override
public EntityManager getEntityManager(String multitenancyIdentifier) {
System.out.println("User Facade: " + multitenancyIdentifier);
return em;
}
public UsuarioFacade() {
super(Usuario.class);
}
}
最后我使用 (userFacade) UsuarioFacade 进行查询:
System.out.println("Test User: " + usuarioFacade.find(1,"usuario1").getNombre());
结果如下:
id find: usuario1|#]
User Facade: usuario1|#]
Identificador schema: null|#]
Test User: Juan Perez Caceres|#]
测试用户:Juan Perez Caceres 在公共模式(PostGres DB)中,但我传递了用户:usuario1,对应于模式:prueba(测试)。 它不会改变shema。
我能做什么? O_o
【问题讨论】: