Как мне переключаться между различными схемами весной JPA и динамически переходить в спящий режимJAVA

Программисты JAVA общаются здесь
Ответить Пред. темаСлед. тема
Anonymous
 Как мне переключаться между различными схемами весной JPA и динамически переходить в спящий режим

Сообщение Anonymous »

У меня есть многопользовательское приложение, написанное с использованием Spring Boot, Keycloak, Flyway и Postgres, мне было трудно переключаться с одной схемы на другую, обратите внимание, что я провел много исследований, и то, что я получил, ограничено выполнением методы запроса jpa, а не пользовательские методы запроса. Вот моя структура кода:
Это мой класс TenantContext

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

public final class TenantContext {
private static final String LOGGER_TENANT_ID = "tenant_id";
public static final String DEFAULT_TENANT = "public";
private static final ThreadLocal CURRENT_TENANT = new ThreadLocal();

private TenantContext() {}

public static String getCurrentTenant() {
String tenant = CURRENT_TENANT.get();
if (tenant != null) {
return tenant;
}
return DEFAULT_TENANT;
}

public static void setCurrentTenant(String tenant) {
MDC.put(LOGGER_TENANT_ID, tenant);
CURRENT_TENANT.set(tenant);
}

public static void clear() {
MDC.clear();
CURRENT_TENANT.remove();
}
}

И мой класс контекстного фильтра:

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

@Component
public class TenantContextFilter implements Filter {
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
try {
if (TenantContext.getCurrentTenant().equals(TenantContext.DEFAULT_TENANT)) {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
if (authentication != null && authentication.getPrincipal() instanceof OidcUser oidcUser) {
String tenant = (String) oidcUser.getAttributes().get("azp");
TenantContext.setCurrentTenant(Constants.PLATFORM_PREFIX + tenant.toLowerCase());
} else if ((authentication instanceof JwtAuthenticationToken jwtAuthenticationToken)) {
Jwt jwt = jwtAuthenticationToken.getToken();
String tenant = jwt.getClaimAsString("azp");
TenantContext.setCurrentTenant(Constants.PLATFORM_PREFIX + tenant.toLowerCase());
} else {
HttpServletRequest httpRequest = (HttpServletRequest) request;
String requestURI = httpRequest.getRequestURI();
if (requestURI.contains("/api/v1/admin")) {
TenantContext.setCurrentTenant("public");
} else {
((HttpServletResponse) response).sendError(HttpServletResponse.SC_UNAUTHORIZED, "Unauthorized");
return;
}
}
}
chain.doFilter(request, response);
} finally {
TenantContext.clear();
}
}

@Override
public void init(FilterConfig filterConfig) throws ServletException {
// Initialization code, if needed
}

@Override
public void destroy() {
// Cleanup code, if needed
}
}
Мой класс HibernateConfig:

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

@Configuration
public class HibernateConfig {

@Autowired
private DataSource dataSource;

@Autowired
private MultiTenantConnectionProviderImpl multiTenantConnectionProvider;

@Autowired
private CurrentTenantIdentifierResolverImpl currentTenantIdentifierResolver;

@Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
em.setDataSource(dataSource);
em.setPackagesToScan("com.mahshellsoft.bims");
HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
em.setJpaVendorAdapter(vendorAdapter);
Map  properties = new HashMap();
properties.put("hibernate.multiTenancy", "SCHEMA");
properties.put("hibernate.multi_tenant_connection_provider", multiTenantConnectionProvider);
properties.put("hibernate.tenant_identifier_resolver", currentTenantIdentifierResolver);
em.setJpaPropertyMap(properties);
return em;
}
}
Мой класс MultiTenantConnectionProviderImpl:

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

@Component
public class MultiTenantConnectionProviderImpl implements MultiTenantConnectionProvider {
@Autowired
private DataSource dataSource;

@Override
public Connection getAnyConnection() throws SQLException {
return dataSource.getConnection();
}

@Override
public void releaseAnyConnection(Connection connection) throws SQLException {
connection.close();
}

@Override
public Connection getConnection(Object tenantIdentifier) throws SQLException {
final Connection connection = getAnyConnection();
try {
MDC.put("schema", tenantIdentifier.toString());
connection.setSchema((String) tenantIdentifier);
connection.createStatement().execute("SET search_path TO " + tenantIdentifier);
} catch (SQLException e) {
throw new HibernateException("Could not set schema to " + tenantIdentifier, e);
}
return connection;
}

@Override
public void releaseConnection(Object tenantIdentifier, Connection connection) throws SQLException {
try {
connection.setSchema("public");
connection.createStatement().execute("SET search_path TO public");
} catch (SQLException e) {
throw new HibernateException("Could not reset schema to public", e);
}
connection.close();
}

@Override
public boolean supportsAggressiveRelease() {
return false;
}

@Override
public boolean isUnwrappableAs(Class unwrapType) {
return unwrapType.isInstance(this);
}

@Override
public  T unwrap(Class unwrapType) {
return (T) this;
}
}
Мой класс CurrentTenantIdentifierResolverImpl:

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

@Component
public class CurrentTenantIdentifierResolverImpl implements CurrentTenantIdentifierResolver {
@Override
public String resolveCurrentTenantIdentifier() {
return TenantContext.getCurrentTenant();
}

@Override
public boolean validateExistingCurrentSessions() {
return true;
}
}
Мой класс JpaConfig:

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

@Configuration
@EnableJpaRepositories(
repositoryBaseClass = CustomJpaRepositoryImpl.class,
repositoryFactoryBeanClass = CustomJpaRepositoryFactoryBean.class,
basePackages = "com.mahshellsoft.bims"
)
@EnableJpaAuditing(auditorAwareRef = "auditorAware")
public class JpaConfig {
}
Мой класс CustomJpaRepositoryFactoryBean:

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

public class CustomJpaRepositoryFactoryBean
extends JpaRepositoryFactoryBean {

public CustomJpaRepositoryFactoryBean(Class

Подробнее здесь: [url]https://stackoverflow.com/questions/78755338/how-do-i-switch-between-different-schemas-in-spring-jpa-and-hibernate-dynamicall[/url]
Реклама
Ответить Пред. темаСлед. тема

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

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

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

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

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

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