我有一个自定义存储库,需要Querydsl和PagingAndSortingRepository
的功能。到目前为止,我的自定义存储库就像
@NoRepositoryBean
public interface CustomPagingSortingQuerydslRepository<T, ID> extends PagingAndSortingRepository<T, ID>, QuerydslPredicateExecutor<T> {
// Overriden methods
}
public class CustomPagingSortingQuerydslRepositoryImpl<T, ID extends Serializable> extends QuerydslJpaRepository<T, ID> implements CustomPagingSortingQuerydslRepository<T, ID> {
// Overriden implementations of methods defined in the interface
}
关于这一点,最棒的是我的自定义实现与QuerydslJpaRepository
提供的默认实现没有太大不同,因此我将使用super
类方法对我的方法进行一些修改,例如
public class CustomPagingSortingQuerydslRepositoryImpl<T, ID extends Serializable> extends QuerydslJpaRepository<T, ID> implements CustomPagingSortingQuerydslRepository<T, ID> {
@Override
@NonNull
public Optional<T> findOne(@NonNull Predicate predicate) {
return super.findOne(modifierMethod(predicate));
}
@Override
@NonNull
public <U extends T> U save(@NonNull U entity) {
return super.save(otherModifierMethod(entity, false));
}
@Override
@NonNull
public <S extends T> S saveCustom(@NonNull S entity) {
return super.save(otherModifierMethod(entity, false));
}
}
请注意,我在自定义界面中还定义了一个saveCustom
,我将在父类的帮助下提供其实现。
这很好用,但是在Spring Boot 2.1之后,不赞成使用QuerydslJpaRepository
,而推荐使用QuerydslJpaPredicateExecutor
。现在,该类不提供save
或delete
的实现,因此,如果我的实现类继承自SimpleJpaRepository
,则无法使用QuerydslJpaPredicateExecutor
方法。
简而言之,我需要在我的自定义存储库中重新实现查询和保存/删除方法以及一些我的自定义方法,我不想从头开始实现它们。当前的弃用意味着我的实现可以从仅提供查询方法实现的QuerydslJpaPredicateExecutor
扩展,也可以从SimpleJpaRepository
扩展,这意味着我在实现中失去了querydsl的功能。
我到目前为止所做的事情
要解决此问题,我创建了2个存储库
@NoRepositoryBean
public interface CustomPagingSortingRepository<T, ID> extends PagingAndSortingRepository<T, ID> {
// Only overrides save and delete type of methods and includes my customSave method
@NoRepositoryBean
public interface CustomQuerydslRepository<T, ID> extends QuerydslPredicateExecutor<T> {
// Overrides all methods of the superclass and includes any custom methods of mine
}
我已经像
那样分别实现了它们@NoRepositoryBean
public class CustomPagingSortingRepositoryImpl<T, ID extends Serializable> extends SimpleJpaRepository<T, ID> implements CustomPagingSortingRepository<T, ID> {
// Implements all the methods of the interface using the parent class methods
}
@NoRepositoryBean
public class CustomQuerydslRepositoryImpl<T, ID extends Serializable> extends QuerydslJpaPredicateExecutor<T> implements CustomQuerydslRepository<T, ID> {
// Implements all the methods of the interface using the parent class methods
}
我将这两个接口继承到我的自定义接口中
@NoRepositoryBean
public interface CustomPagingSortingQuerydslRepository<T, ID> extends CustomPagingSortingRepository<T,ID>,CustomQuerydslRepository<T, ID> {
}
我认为这可以工作,但是会引发类型错误,在仔细检查后发现,这是因为Spring试图自行创建customSave
的实现,并且由于它不了解该方法必须执行的操作这样做会引发错误。
由于不推荐使用的方法非常干净,我现在已经在修复中,并且我不想实现六个Bean来使它正常工作。
PS
我一直在考虑使用Composition而不是Inheritance来获取SimpleJpaRepository
和QuerydslJpaPredicateExecutor
的句柄,并以这种方式使用它们中的方法,但是我感到这将不利于注入和不良实践。