Table per tenant not working [message #1809043] |
Sun, 07 July 2019 18:26  |
ercan celik Messages: 3 Registered: February 2010 |
Junior Member |
|
|
I am trying to implement table per tenant solution using Eclipselink 2.7.4 with Spring Boot 2.1.5.
Although I set tenant information to EntityManager before the transaction starts, EclipseLink tries to query the other tenant's table which i have to set in application.properties file.
Here is my JPA configuration
@Configuration
@EnableTransactionManagement
public class JpaConfiguration extends JpaBaseConfiguration {
protected JpaConfiguration(DataSource dataSource, JpaProperties properties, ObjectProvider<JtaTransactionManager> jtaTransactionManager, ObjectProvider<TransactionManagerCustomizers> transactionManagerCustomizers) {
super(dataSource, properties, jtaTransactionManager, transactionManagerCustomizers);
}
@Override
protected AbstractJpaVendorAdapter createJpaVendorAdapter() {
return new EclipseLinkJpaVendorAdapter();
}
@Override
protected Map<String, Object> getVendorProperties() {
return new HashMap<>(0);
}
@Bean("transactionManager")
public PlatformTransactionManager createTransactionManager(EntityManagerFactory entityManagerFactory) {
TenantAwareJpaTransactionManager txManager = new TenantAwareJpaTransactionManager();
txManager.setEntityManagerFactory(entityManagerFactory);
return txManager;
}
}
And this is the Transaction Manager
@Slf4j
public class TenantAwareJpaTransactionManager extends JpaTransactionManager {
@Override
protected void doBegin(Object transaction, TransactionDefinition definition) {
super.doBegin(transaction, definition);
final EntityManagerHolder emHolder = (EntityManagerHolder) TransactionSynchronizationManager.getResource(getEntityManagerFactory());
final EntityManager em = emHolder.getEntityManager();
String tenant = TenantContext.getCurrentTenant();
if (StringUtils.isEmpty(tenant)) {
throw new NoTenantProvidedException();
}
log.info("{} is set to EntityManager", tenant);
em.setProperty(EntityManagerProperties.MULTITENANT_PROPERTY_DEFAULT, tenant);
}
class NoTenantProvidedException extends RuntimeException {
public NoTenantProvidedException() {
super("No tenant identifier could be resolved instance.");
}
}
}
And this is the service
@Slf4j
@Service
public class CustomerService {
@PersistenceContext
EntityManager entityManager;
private final CustomerRepository customerRepository;
public CustomerService(CustomerRepository customerRepository) {
this.customerRepository = customerRepository;
}
@Transactional
public Customer add(Customer customer) {
setTenant();
return this.customerRepository.save(customer);
}
@Transactional
public Customer update(Long customerId, Customer customer) {
setTenant();
Optional<Customer> temp = this.customerRepository.findById(customerId);
if (temp.isPresent()) {
temp.get().setFirstName(customer.getFirstName());
temp.get().setLastName(customer.getLastName());
return temp.get();
}
return null;
}
@Transactional(readOnly = true, propagation = Propagation.REQUIRES_NEW)
public List<Customer> getAll() {
setTenant();
return this.customerRepository.findAll();
}
@Transactional
public void delete(Long customerId) {
setTenant();
Optional<Customer> temp = this.customerRepository.findById(customerId);
if (temp.isPresent()) {
this.customerRepository.delete(temp.get());
}
}
private void setTenant(){
log.info("Current tenant : {}", TenantContext.getCurrentTenant());
this.entityManager.setProperty(EntityManagerProperties.MULTITENANT_PROPERTY_DEFAULT, TenantContext.getCurrentTenant());
}
}
You could find all the other related classes here -> https://github.com/ercancelik/eclipselink-multitenant
I am using shared Entity Manager. Do I need to use separate EntityManager per tenant?
Note:
After running the project, you should execute the ddls in src/main/resources/ddl.sql file in H2 console -> http://localhost:8080/console/login.jsp.
After that you can run the curl command to see the error. Although I set TENANT2 to the request headers, it tries to query TENANT1's table.
curl -X GET http://localhost:8080/customers -H 'Accept: application/json' -H 'X-TenantID: TENANT2'
|
|
|
|
|
|
|
Powered by
FUDForum. Page generated in 0.01979 seconds