Hibernate Multitenancy: изменение арендатора в сеансе (подход с использованием столбца дискриминатора)JAVA

Программисты JAVA общаются здесь
Ответить Пред. темаСлед. тема
Anonymous
 Hibernate Multitenancy: изменение арендатора в сеансе (подход с использованием столбца дискриминатора)

Сообщение Anonymous »

Я разрабатываю приложение Springboot, которое предоставляет данные нескольким арендаторам. Для разделения данных между арендаторами я использую интегрированные функции мультиарендности hibernates для разделения на основе столбцов дискриминатора (аннотация (@TenantId). Поэтому мне пришлось реализовать CurrentTenantIdentifierResolver, который переведет в спящий режим текущего клиента для запроса.

Код: Выделить всё

@Component
public class CurrentTenantIdentifierResolverImpl implements CurrentTenantIdentifierResolver, HibernatePropertiesCustomizer {

private static Logger LOGGER = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
public static final String DEFAULT_TENANT_ID = "notenant";

@Override
public String resolveCurrentTenantIdentifier() {

String tenant = TenantContext.getCurrentTenant();

if (tenant == null) {
return DEFAULT_TENANT_ID;
}

return tenant;
}

@Override
public void customize(Map hibernateProperties) {
hibernateProperties.put(AvailableSettings.MULTI_TENANT_IDENTIFIER_RESOLVER, this);
}

@Override
public boolean validateExistingCurrentSessions() {
return true;
}
}
Все работает нормально, однако я столкнулся со следующей проблемой:
Для некоторых методов я хочу переключаться между арендаторами в одном запросе. Hibernate сохраняет tenantId, полученный из CurrentTenantIdentifierResolver, в сеансе, который он создает в начале запроса, но после создания сеанса невозможно изменить tenantId (или, по крайней мере, я еще не нашел чистого способа) . Мне удалось реализовать обходной путь, который просто отвязывает текущий сеанс и создает новый, однако это создает проблему, заключающуюся в том, что я не могу сделать методы, использующие этот «переключатель арендатора», транзакционными. Кроме того, это похоже на грязный обходной путь.
Вот код моего обходного пути («переключение арендатора»). TenantContext — это просто переменная ThreadLocal, в которой хранится идентификатор tenantId, указанный в заголовке запроса. CurrentTenantIdentifierResolver просто возвращает значение этой переменной, когда она вызывается из спящего режима.

Код: Выделить всё

@Override
public void changeTenant(String tenantId) {
unbindSession();
TenantContext.setCurrentTenant(tenantId); //ThreadLocal variable which holds the current tenant
bindSession();
}

@Override
public void bindSession() {
if (!TransactionSynchronizationManager.hasResource(entityManagerFactory)) {
EntityManager entityManager = entityManagerFactory.createEntityManager();
TransactionSynchronizationManager.bindResource(entityManagerFactory, new EntityManagerHolder(entityManager));
}
}

@Override
public void unbindSession() {
if (TransactionSynchronizationManager.hasResource(entityManagerFactory)) {
EntityManagerHolder emHolder = (EntityManagerHolder) TransactionSynchronizationManager.unbindResource(entityManagerFactory);
EntityManagerFactoryUtils.closeEntityManager(emHolder.getEntityManager());
}
}
Я уже много искал на различных форумах и проверял документацию Hibernate, но не смог найти четкого способа решения этой проблемы. Кто-нибудь знает, как лучше всего решить эту проблему?
В конечном итоге я бы хотел написать такой код:

Код: Выделить всё

@Transactional    // Not possible with current solution
@Override
public void someServiceMethod() {
Information info = repository.getInfo()   // Gets some data from tenant which made the request
changeTenant(someOtherTenantId)           // Change the tenant without replacing the session
Information info2 = repository.getInfo()  // Gets data for someOtherTenantId

// Perform other calculations etc.
}
Заранее спасибо!

Подробнее здесь: https://stackoverflow.com/questions/792 ... n-approach
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «JAVA»