EclipseLink + SpringDataJPA:单表MultiTenancy-TENANT_ID未添加到DELETE和UPDATE的WHERE子句中

时间:2014-03-13 05:57:14

标签: eclipselink spring-data-jpa delete-row sql-delete multi-tenant

我使用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

  • userRepository.findOne(用户名);
  • userRepository.save(user) - FOR CREATE OPERATION
  • userRepository.findAll()
  • userRepository.findByFirstName(userName) - 这是
  • 中定义的自定义方法

但是下面提到的操作不会自动添加TENANT_ID

  • userRepository.deleteAll()
  • userRepository.delete(用户名)
  • userRepository.save(user) - FOR UPDATE OPERATION

我无法找到解决此问题的任何解决方案,并担心对于少数操作,它工作正常,很少没有。

下面是我的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
}

还有两个类 - CustomizedSimpleJpaRepositoryFactoryCustomizedSimpleJpaRepositoryFactoryBean,但我不会为那些类添加代码,因为它不需要。

为什么不为上面提到的DELETE和UPDATE操作添加TENANT_ID到WHERE子句。?

0 个答案:

没有答案