I am using EclipseLink And Spring Data JPA for Single Table Multi-Tenancy.(DISCRIMINATOR based model).
I have customized Spring Data JPA SimpleJPAReposity
to add below mentioned and required property on EntityManager
.
em.setProperty(PersistenceUnitProperties.MULTITENANT_PROPERTY_DEFAULT,"TENANT_1");
Every Spring Data JPA operations are now handled by CustomizedSimpleJpaRepository
.
I have configured it successfully and below all Spring DATA JPA operations are working fine, they are automatically adding TENANT_ID
to WHERE
clause and also set that property to TENANT_1.
- userRepository.findOne(userName);
- userRepository.save(user) - FOR CREATE OPERATION
- userRepository.findAll()
- userRepository.findByFirstName(userName) - This is custom method defined in
But TENANT_ID is not automatically added for below mentioned operations
- userRepository.deleteAll()
- userRepository.delete(userName)
- userRepository.save(user) - FOR UPDATE OPERATION
I am not able to find any solution for this problem, and worried that for few operations, it is working fine and few not.
Below is my UserRepository
and custom SimpleJPARepository
which I extends in order to use EclipseLink as stated above.
UserRepository
public interface UserRepository extends CustomizedSimpleJpaRepository<User, String>, JpaSpecificationExecutor<User>{
User findUserByUserName(String userName);
User findUserByFirstName(String firstName);
}
CustomizedSimpleJpaRepository
public interface CustomizedSimpleJpaRepository<T, ID extends Serializable> extends JpaRepository<T, ID> {
}
CustomizedSimpleJpaRepositoryImpl
public class CustomizedSimpleJpaRepositoryImpl<T, ID extends Serializable> extends
SimpleJpaRepository<T, ID> implements
CustomizedSimpleJpaRepository<T, ID> {
private final CurrentTenantResolver tenantResolver;
private final EntityManager em;
public CustomizedSimpleJpaRepositoryImpl(
JpaEntityInformation<T, ?> entityInformation, EntityManager em,
CurrentTenantResolver tenantResolver) {
super(entityInformation, em);
em.setProperty(PersistenceUnitProperties.MULTITENANT_PROPERTY_DEFAULT,tenantResolver.getCurrentTenantId());
this.tenantResolver = tenantResolver;
this.em = em;
}
public CustomizedSimpleJpaRepositoryImpl(Class<T> domainClass,
EntityManager em, CurrentTenantResolver tenantResolver) {
super(domainClass, em);
this.tenantResolver = tenantResolver;
this.em = em;
}
protected void setCurrentTenant() {
em.setProperty(PersistenceUnitProperties.MULTITENANT_PROPERTY_DEFAULT,
tenantResolver.getCurrentTenantId());
}
@Override
public <S extends T> S save(S entity) {
setCurrentTenant();
return super.save(entity);
}
@Override
public void delete(ID id) {
setCurrentTenant();
super.delete(id);
};
/*@Override
public void delete(T entity) {
setCurrentTenant();
super.delete(entity);
};
*/
@Override
public T findOne(ID id) {
setCurrentTenant();
return super.findOne(id);
};
@Override
public List<T> findAll() {
setCurrentTenant();
return super.findAll();
}
/*
* (non-Javadoc)
*
* @see
* org.springframework.data.repository.PagingAndSortingRepository#findAll
* (org.springframework.data.domain.Sort)
*/
@Override
public List<T> findAll(Sort sort) {
setCurrentTenant();
return super.findAll(sort);
}
@Override
public List<T> findAll(Iterable<ID> ids) {
setCurrentTenant();
return super.findAll(ids);
}
/*
* (non-Javadoc)
*
* @see
* org.springframework.data.repository.CrudRepository#save(java.lang.Iterable
* )
*/
@Override
public <S extends T> List<S> save(Iterable<S> entities) {
setCurrentTenant();
return super.save(entities);
}
/**
* Flushes all pending changes to the database.
*/
@Override
public void flush() {
setCurrentTenant();
super.flush();
}
/**
* Saves an entity and flushes changes instantly.
*
* @param entity
* @return the saved entity
*/
@Override
public T saveAndFlush(T entity) {
setCurrentTenant();
return super.saveAndFlush(entity);
}
/**
* Deletes the given entities in a batch which means it will create a single
* {@link Query}. Assume that we will clear the
* {@link javax.persistence.EntityManager} after the call.
*
* @param entities
*/
@Override
public void deleteInBatch(Iterable<T> entities) {
setCurrentTenant();
super.deleteInBatch(entities);
}
/**
* Deletes all entites in a batch call.
*/
@Override
public void deleteAllInBatch() {
setCurrentTenant();
super.deleteAllInBatch();
}
// override the other methods
}
Two more classes are there- CustomizedSimpleJpaRepositoryFactory
and CustomizedSimpleJpaRepositoryFactoryBean
, but I am not adding code for those as it is not needed.
Why it is not adding TENANT_ID to WHERE clause for above stated operation for DELETE and UPDATE.?