我正在努力使用Hibernate在我的基于Spring的应用程序中启用多租户。我创建了一个自定义实现的MONtTenantIdfierResolver
和重写的解析器MONtTenant标识符()
方法来确定租户标识符。当我提供硬编码的租户标识符时,应用程序工作正常。
但是随后出现了一个要求,即根据请求头中的值从数据库默认模式中的表中获取租户标识符。我在许多地方搜索了这个问题,并做了一些打击和试验,但收效甚微。
任何有关这方面的帮助都将不胜感激。请让我知道我需要提供哪些信息来更好地理解问题场景。
CustomTenantIdentifier解析程序。JAVA
public class CustomTenantIdentifierResolver implements CurrentTenantIdentifierResolver {
public static final String DEFAULT_TENANT_SCHEMA = "public";
@Override
public String resolveCurrentTenantIdentifier() {
try {
Provider<TenantRequestContext> tenantProvider = SpringContext
.getBean(Provider.class);
if (tenantProvider == null) {
return DEFAULT_TENANT_SCHEMA;
} else {
TenantRequestContext tenantRequestContext = tenantProvider
.get();
String tenantId = tenantRequestContext.getTenantIdValue();
String tenantSchema = tenantRequestContext.getTenantSchema(tenantId);
return tenantSchema;
}
} catch (Exception ex) {
return DEFAULT_TENANT_SCHEMA;
}
// return "myschema";
}
@Override
public boolean validateExistingCurrentSessions() {
return true;
}
}
租户请求ContextImpl。JAVA
@Component
@Scope(value = WebApplicationContext.SCOPE_REQUEST, proxyMode = ScopedProxyMode.TARGET_CLASS)
public class TenantRequestContextImpl implements TenantRequestContext{
@Autowired
private TenantReadService tenantReadService;
@Override
public String getTenantIdValue() {
String tenantId =((ServletRequestAttributes)RequestContextHolder.currentRequestAttributes())
.getRequest().getHeader("tenantId");
return tenantId;
}
@Override
public String getTenantSchema(String tenantId) {
Tenant tenant = tenantReadService.findById(Integer.parseInt(tenantId));
return tenant.getTenantSchemaName();
}
}
租户服务impl。JAVA
@Repository
public class TenantReadServiceImpl implements TenantReadService {
@Autowired
private SessionFactory defaultSessionFactory;
public TenantReadServiceImpl() {
}
public TenantReadServiceImpl(SessionFactory defaultSessionFactory) {
this.defaultSessionFactory = defaultSessionFactory;
}
@Override
@Transactional
public Tenant findById(Integer tenantId) {
String hql = "from Tenant where id=" + tenantId;
Query query = defaultSessionFactory.getCurrentSession().createQuery(hql);
Tenant tenant = (Tenant) query.uniqueResult();
defaultSessionFactory.getCurrentSession().clear();
return tenant;
}
}
MultiTenancPlatformConfig。JAVA
@Configuration
@EnableTransactionManagement
@ComponentScan("com.mypackage")
public class MultitenancyPlatformConfig {
@Bean(name="defaultDataSource")
public DataSource dataSource() {
final JndiDataSourceLookup dsLookup = new JndiDataSourceLookup();
DataSource dataSource = dsLookup.getDataSource(java:comp/env/jdbc/myDataSource);
return dataSource;
}
@Autowired
@Bean(name = "defaultSessionFactory")
public SessionFactory getSessionFactory(DataSource defaultDataSource) {
LocalSessionFactoryBuilder sessionBuilder = new LocalSessionFactoryBuilder(
defaultDataSource);
sessionBuilder.addAnnotatedClasses(Tenant.class);
sessionBuilder.addProperties(hibProperties());
return sessionBuilder.buildSessionFactory();
}
private Properties hibProperties() {
Properties properties = new Properties();
properties.put("hibernate.format_sql",
"true");
properties.put("hibernate.dialect",
"org.hibernate.dialect.PostgreSQLDialect");
properties.put("hibernate.default_schema", "public");
return properties;
}
@Autowired
@Bean(name = "tenantReadService")
public TenantReadService getTenantReadService(SessionFactory defaultSessionFactory) {
return new TenantReadServiceImpl(defaultSessionFactory);
}
}
MyPlatformConfig.java
@Configuration
@EnableTransactionManagement
@ComponentScan("com.mypackage")
@EnableJpaRepositories("com.mypackage.repository")
public class MyPlatformConfig {
@Bean
public DataSource dataSource() {
final JndiDataSourceLookup dsLookup = new JndiDataSourceLookup();
DataSource dataSource = dsLookup.getDataSource("java:comp/env/jdbc/ihubDataSource");
return dataSource;
}
@Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
vendorAdapter.setGenerateDdl(false);
vendorAdapter.setDatabase(Database.POSTGRESQL);
vendorAdapter.setDatabasePlatform("org.postgresql.Driver");
LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean();
factory.setJpaVendorAdapter(vendorAdapter);
factory.setPackagesToScan("com.mypackage.entity");
factory.setJpaProperties(hibProperties());
return factory;
}
private Properties hibProperties() {
Properties properties = new Properties();
properties.put("hibernate.dialect","org.hibernate.dialect.PostgreSQLDialect");
properties.put("hibernate.format_sql","true");
properties.put("hibernate.tenant_identifier_resolver"," com.mypackage.tenantresolvers.CustomTenantIdentifierResolver");
properties.put("hibernate.multi_tenant_connection_provider", "com.mypackage.connectionproviders.MultiTenantConnectionProviderImpl");
properties.put("hibernate.multiTenancy", "SCHEMA");
return properties;
}
@Bean
public JpaTransactionManager transactionManager() {
JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(entityManagerFactory().getObject());
return transactionManager;
}
}
以下是我解决这个问题的方法:
resolveCurrentTenantIdentifier
中,只需从ThreadLocal返回值
我们正面临着解决这个问题的艰难时刻!我们正在尝试在不使用默认租户的情况下为Spring Boot服务使用MTA。这意味着当当前上下文中没有租户时,我们希望从我们的CurrentTenantIdentifierResolver实现返回null。这在我们用JavaEE+Hibernate+Deltaspike数据构建的其他服务中运行良好,但在Spring服务启动时失败。 异常消息如下:“由:org.h
编辑:这个问题已经过时了 在我问这个问题的时候,身份框架是一个移动的目标。作者改变了相当多的东西,他们已经脱钩了其他几个,使一切变得更容易。 看一下GitHub上的ASP.NET标识示例项目。 我得到一个异常。ApplicationDbContext的定义由新建应用程序向导自动生成: 因此,我的猜测是,列用于区分和。但是,它不存在于我的数据库中(该数据库是由应用程序自动创建的)
问题内容: 我的对象是: 函数的类别是: 当我尝试使用此功能时: 它不和我一起工作,有帮助吗?!!! 问题答案: 我用这个类来解决这个问题: 然后我用这个功能来使用它
我正在使用Drools 6.3.0决赛。假设我有这样的规则 让我们进一步假设我用这个规则构建了KieSession,添加了一些事实,现在我想知道所有规则/所有与我的事实匹配的规则中使用的标识符。 所以我想在这里得到的是$人和$孩子。 我知道我可以获取使用AgendaEventListener触发的规则,从事件中我可以获取规则的名称,以及$person和$child的对象。但我没有找到从匹配中获取标
本文向大家介绍如何在Android中获取默认手机IMEI?,包括了如何在Android中获取默认手机IMEI?的使用技巧和注意事项,需要的朋友参考一下 此示例演示了如何在android中获取默认手机IMEI。 步骤1-在Android Studio中创建一个新项目,转到File⇒New Project并填写所有必需的详细信息以创建一个新项目。 步骤2-将以下代码添加到res / layout /
我有两个存储桶,一个来自谷歌云存储,一个由firebase创建,firebase创建的存储桶是默认的,我想更改默认的存储桶并删除firebase创建的存储桶。