[英]Group by in Query DSL + Spring Data JPA throwing NoSuchElementException
我正在嘗試使用Spring Data JPA和Query DSL按組執行查詢。
但是,我得到以下異常:
org.springframework.beans.factory.UnsatisfiedDependencyException:
Error creating bean with name 'japanWHTDaoImpl':
Unsatisfied dependency expressed through field 'wht21940000DataRepo';
nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'japanWHT21940000DataRepository':
Invocation of init method failed; nested exception is java.util.NoSuchElementException
我試圖編寫自定義存儲庫實現,並在下面的接口和impl類中給出以下信息:
自定義界面:
public interface JapanWHT21940000DataRepositoryCustom {
List<WHT21940000Royalties> findLocalCcyAmtsByRemarks();
}
自定義Impl類:
@Repository
@Transactional
public class JapanWHT21940000DataRepositoryCustomImpl extends QueryDslRepositorySupport implements JapanWHT21940000DataRepositoryCustom {
public JapanWHT21940000DataRepositoryCustomImpl(Class<?> domainClass) {
super(domainClass);
// TODO Auto-generated constructor stub
}
@PersistenceContext
private EntityManager entityManager;
@Override
public List<WHT21940000Royalties> findLocalCcyAmtsByRemarks() {
QWHT21940000Data wht21940000Data = QWHT21940000Data.wHT21940000Data;
JPAQuery<WHT21940000Royalties> query = new JPAQuery<WHT21940000Royalties>(entityManager);
query.from(wht21940000Data).groupBy(wht21940000Data.remarks).select(wht21940000Data.remarks, wht21940000Data.localCcyAmt.sum());
return null;
}
}
Spring數據JPA接口:
public interface JapanWHT21940000DataRepository
extends JpaRepository<WHT21940000Data, Long>,
QueryDslPredicateExecutor<WHT21940000Data>,
JapanWHT21940000DataRepositoryCustom {
}
在DAO類中:
@Repository
@Transactional("japanWhtTransactionManager")
public class JapanWHTDaoImpl implements JapanWHTDao {
@Autowired
JapanWHT21940000DataRepository wht21940000DataRepo;
// more code to follow...
編輯:還是有比我正在嘗試的方法更簡單更好的方法來按Spring數據JPA +查詢DSL進行分組查詢?
我認為真正的問題是從JpaRepositories執行定制的querydsl查詢,盡管我建議使用定制的擴展基礎存儲庫類,如下所示。
首先,擴展基礎存儲庫類。
@NoRepositoryBean
public interface ExtendedQueryDslJpaRepository<T, ID extends Serializable> extends JpaRepository<T, ID>, QueryDslPredicateExecutor<T> {
<T1> Page<T1> findAll(JPQLQuery jpqlQuery, Pageable pageable);
}
和相關的實現。
public class ExtendedQueryDslJpaRepositoryImpl<T, ID extends Serializable>
extends QueryDslJpaRepository<T, ID> implements ExtendedQueryDslJpaRepository<T, ID> {
private static final EntityPathResolver DEFAULT_ENTITY_PATH_RESOLVER = SimpleEntityPathResolver.INSTANCE;
private final EntityPath<T> path;
private final PathBuilder<T> builder;
private final Querydsl querydsl;
private EntityManager entityManager;
public ExtendedQueryDslJpaRepositoryImpl(JpaEntityInformation<T, ID> entityInformation, EntityManager entityManager) {
this(entityInformation, entityManager, DEFAULT_ENTITY_PATH_RESOLVER);
}
public ExtendedQueryDslJpaRepositoryImpl(JpaEntityInformation<T, ID> entityInformation, EntityManager entityManager, EntityPathResolver
resolver) {
super(entityInformation, entityManager);
this.path = resolver.createPath(entityInformation.getJavaType());
this.builder = new PathBuilder(this.path.getType(), this.path.getMetadata());
this.querydsl = new Querydsl(entityManager, this.builder);
this.entityManager = entityManager;
}
@Override
public <T1> Page<T1> findAll(JPQLQuery jpqlQuery, Pageable pageable) {
final JPQLQuery<?> countQuery = jpqlQuery;
JPQLQuery<T1> query = querydsl.applyPagination(pageable, jpqlQuery);
return PageableExecutionUtils.getPage(query.fetch(), pageable, countQuery::fetchCount);
}
}
上面的類可以放在配置包中。
然后,我們將ExtendedQueryDslJpaRepositoryImpl
定義為JpaRepository
類應從其ExtendedQueryDslJpaRepositoryImpl
默認類,如下所示:
@Configuration
@EnableJpaRepositories(basePackageClasses = Application.class, repositoryBaseClass = ExtendedQueryDslJpaRepositoryImpl.class)
public class JpaConfig {
@PersistenceContext
private EntityManager entityManager;
@Bean
public JPAQueryFactory jpaQueryFactory() {
return new JPAQueryFactory(entityManager);
}
}
下一步是為應用程序的Entity
定義存儲庫,例如。 CustomEntity
。
public interface CustomRepository extends ExtendedQueryDslJpaRepository<CustomEntity, Long>, CustomRepositorySupport {
}
接下來,我們為自定義方法定義定義接口CustomRepositorySupport
。
public interface CustomRepositorySupport {
JPQLQuery<CustomListDto> createCustomIndexQuery();
}
最后是自定義存儲庫實現。
@Repository
public class CustomRepositoryImpl implements CustomRepositorySupport {
private JPAQueryFactory queryFactory;
@Autowired
public CustomRepositoryImpl(JPAQueryFactory queryFactory) {
this.queryFactory = queryFactory;
}
@Override
public JPQLQuery<CustomListDto> createCustomIndexQuery() {
QCustomEntity qCustomEntity = QCustomEntity.customEntity;
BooleanBuilder predicate = new BooleanBuilder();
// Create predicate as desired
// predicate.and(...);
// Create projection of fields
/* FactoryExpression<CustomListDto> factoryExpression = Projections.bean(CustomListDto.class,
qCustomEntity.fieldA,
qCustomEntity.fieldB,
qCustomEntity.fieldC,
qCustomEntity.fieldD,
qCustomEntity.fieldE,
qCustomEntity.fieldF); */
return queryFactory.from(qCustomEntity).select(factoryExpression).where(predicate);
}
}
最后一步是從Service
類實際調用該方法,如下所示。
public interface CustomFinder {
Page<CustomListDto> findIndex(Pageable pageable);
}
--
@Service
public class CustomFinderImpl implements CustomFinder {
private CustomRepository customRepository;
@Autowired
public CustomFinderImpl(CustomRepository customRepository) {
this.customRepository = customRepository;
}
@Override
public Page<CustomListDto> findIndex(Pageable pageable) {
JPQLQuery<CustomListDto> query = customRepository.createCustomIndexQuery();
return customRepository.findAll(query, pageable);
}
}
與我們實現public <T1> List<T1> findAll(JPQLQuery query, FactoryExpression<T1> factoryExpression)
,我們可以簡單地實現所需的所需方法,如public <T1> List<T1> findAll(JPQLQuery query, FactoryExpression<T1> factoryExpression)
<T1> List<T1> findList(JPQLQuery query, FactoryExpression<T1> factoryExpression)
等
這樣,我們為所有存儲庫添加了功能,以便利用所有類型的querydsl查詢,而不僅是group by
或projections
。
它看起來似乎有些復雜,但是如果您選擇實現它,並查看它如何工作,則您會堅持下去。 它已在實際應用程序中成功使用,可以訪問投影查詢(無需在不需要它們的情況下加載完整實體),分頁查詢,存在子查詢等。
最后,使用一種中央基礎存儲庫類是一種僅可編寫一次的可重用代碼。
希望能有所幫助。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.