我尝试为我的所有存储库实现自定义功能(我使用 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 功能可以正常工作,但自定义覆盖则不行。保存和删除功能不会被覆盖。调用它们时会执行原始父方法。