我使用EclipseLink和Spring Data JPA进行单表多租户。(基于DISCRIMINATOR的模型)。
我已定制Spring Data JPA SimpleJPAReposity
以在EntityManager
添加以下提及的必需属性。
em.setProperty(PersistenceUnitProperties.MULTITENANT_PROPERTY_DEFAULT,"TENANT_1");
每个Spring Data JPA操作现在由CustomizedSimpleJpaRepository
处理。
我已成功配置它,并且在所有Spring DATA JPA操作正常工作之后,它们会自动将TENANT_ID
添加到WHERE
子句,并将该属性设置为 TENANT_1 。
但是下面提到的操作不会自动添加TENANT_ID
我无法找到解决此问题的任何解决方案,并担心对于少数操作,它工作正常,很少没有。
下面是我的UserRepository
和自定义SimpleJPARepository
,我将其扩展为使用EclipseLink,如上所述。
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
}
还有两个类 - CustomizedSimpleJpaRepositoryFactory
和CustomizedSimpleJpaRepositoryFactoryBean
,但我不会为那些类添加代码,因为它不需要。
为什么不为上面提到的DELETE和UPDATE操作添加TENANT_ID到WHERE子句。?