1

我尝试为我的所有存储库实现自定义功能(我使用 Packt Spring Data 示例作为基础)。我想覆盖一些默认行为。

首先我实现了:

@NoRepositoryBean
public interface BaseRepository<T extends AbstractModel, ID extends Serializable> extends JpaRepository<T, ID>, QueryDslPredicateExecutor<T> {

    @Override
    public void delete(final T t);

    public T save(final T entity);  
}

AbstractModel 用于逻辑删除:

public interface AbstractModel {

    public boolean isDeleted();

    public void setDeleted(boolean deleted);
}

GenericBaseRepository实现自定义功能。我需要逻辑删除功能。而且我想覆盖保存以使用始终合并来处理级联对象的保存。

public class GenericBaseRepository<T extends AbstractModel, ID extends Serializable> extends QueryDslJpaRepository<T, ID> implements BaseRepository<T, ID> {

    protected final Logger logger = LoggerFactory.getLogger(getClass());

    @PersistenceContext
    private EntityManager entityManager;

    Class<T> type;

    public GenericBaseRepository(final JpaEntityInformation<T, ID> entityMetadata, final EntityManager entityManager) {
        super(entityMetadata, entityManager);
    }

    @Override
    public void delete(final T t) {
        t.setDeleted(true);
        save(t);
    }

    @Override
    public void delete(final ID id) {
        final T deleted = findOne(id);

        if (deleted == null) {
            logger.warn("{} Record not found: id={}", getClass(), id);
        }

        deleted.setDeleted(true);
        save(deleted);
    }

    @Override
    @Transactional
    public <S extends T> S save(final S entity) {
        return entityManager.merge(entity);
    }
}

BaseRepositoryFactoryBean初始化GenericBaseRepository

public class BaseRepositoryFactoryBean<R extends JpaRepository<T, I>, T, I extends Serializable> extends JpaRepositoryFactoryBean<R, T, I> {

    @Override
    protected RepositoryFactorySupport createRepositoryFactory(final EntityManager entityManager) {
        return new BaseRepositoryFactory(entityManager);
    }

    protected static class BaseRepositoryFactory<T extends AbstractModel, I extends Serializable> extends JpaRepositoryFactory {

        private final EntityManager entityManager;

        public BaseRepositoryFactory(final EntityManager entityManager) {
            super(entityManager);

            this.entityManager = entityManager;
        }

        @Override
        protected Object getTargetRepository(final RepositoryMetadata metadata) {
            return new GenericBaseRepository<T, I>((JpaEntityInformation<T, I>) getEntityInformation(metadata.getDomainType()), entityManager);
        }

        @Override
        protected Class<?> getRepositoryBaseClass(final RepositoryMetadata metadata) {
            return GenericBaseRepository.class;
        }
    }
}

这是spring config xml的相关部分:

<jpa:repositories base-package="sample.project.repository" />

自定义类和接口在这个包中,也有具体的存储库接口。

我的@Configuration班级也有配置注释

@Configuration
@EnableTransactionManagement
@ComponentScan({"sample.project.repository", "sample.project.service"})
@ImportResource({"classpath:applicationContext.xml"})
@EnableJpaRepositories(basePackages = {"sample.project.repository"}, repositoryFactoryBeanClass = BaseRepositoryFactoryBean.class)
public class ApplicationContextConfig {

标准 Spring Data 功能可以正常工作,但自定义覆盖则不行。保存和删除功能不会被覆盖。调用它们时会执行原始父方法。

4

0 回答 0