use of io.micronaut.data.model.query.JoinPath in project micronaut-data by micronaut-projects.
the class QueryCriteriaMethodMatch method build.
@Override
protected MethodMatchInfo build(MethodMatchContext matchContext) {
ClassElement queryResultType = matchContext.getRootEntity().getClassElement();
MethodMatchSourcePersistentEntityCriteriaBuilderImpl cb = new MethodMatchSourcePersistentEntityCriteriaBuilderImpl(matchContext);
PersistentEntityCriteriaQuery<Object> criteriaQuery = cb.createQuery();
apply(matchContext, criteriaQuery.from(matchContext.getRootEntity()), criteriaQuery, cb);
Map.Entry<ClassElement, Class<? extends DataInterceptor>> entry = resolveReturnTypeAndInterceptor(matchContext);
ClassElement resultType = entry.getKey();
Class<? extends DataInterceptor> interceptorType = entry.getValue();
boolean optimisticLock = ((AbstractPersistentEntityCriteriaQuery<?>) criteriaQuery).hasVersionRestriction();
SourcePersistentEntityCriteriaQuery<?> query = (SourcePersistentEntityCriteriaQuery) criteriaQuery;
String selectedType = query.getQueryResultTypeName();
if (selectedType != null) {
queryResultType = matchContext.getVisitorContext().getClassElement(selectedType).orElse(null);
if (queryResultType == null) {
try {
queryResultType = PrimitiveElement.valueOf(selectedType);
} catch (Exception e) {
// Ignore
}
}
}
boolean isDto = resultType != null && !TypeUtils.areTypesCompatible(resultType, queryResultType) && (isDtoType(resultType) || resultType.hasStereotype(Introspected.class) && queryResultType.hasStereotype(MappedEntity.class));
if (isDto) {
if (!isDtoType(resultType)) {
List<SourcePersistentProperty> dtoProjectionProperties = getDtoProjectionProperties(matchContext.getRootEntity(), resultType);
if (!dtoProjectionProperties.isEmpty()) {
Root<?> root = query.getRoots().iterator().next();
query.multiselect(dtoProjectionProperties.stream().map(p -> {
if (matchContext.getQueryBuilder().shouldAliasProjections()) {
return root.get(p.getName()).alias(p.getName());
} else {
return root.get(p.getName());
}
}).collect(Collectors.toList()));
}
}
} else {
if (resultType == null || (!resultType.isAssignable(void.class) && !resultType.isAssignable(Void.class))) {
if (resultType == null || TypeUtils.areTypesCompatible(resultType, queryResultType)) {
if (!queryResultType.isPrimitive() || resultType == null) {
resultType = queryResultType;
}
} else {
throw new MatchFailedException("Query results in a type [" + queryResultType.getName() + "] whilst method returns an incompatible type: " + resultType.getName());
}
}
}
final AnnotationMetadataHierarchy annotationMetadataHierarchy = new AnnotationMetadataHierarchy(matchContext.getRepositoryClass().getAnnotationMetadata(), matchContext.getAnnotationMetadata());
QueryBuilder queryBuilder = matchContext.getQueryBuilder();
QueryModel queryModel = ((QueryModelPersistentEntityCriteriaQuery) criteriaQuery).getQueryModel();
QueryResult queryResult = queryBuilder.buildQuery(annotationMetadataHierarchy, queryModel);
ClassElement genericReturnType = matchContext.getReturnType();
if (TypeUtils.isReactiveOrFuture(genericReturnType)) {
genericReturnType = genericReturnType.getFirstTypeArgument().orElse(matchContext.getRootEntity().getType());
}
QueryResult countQueryResult = null;
if (matchContext.isTypeInRole(genericReturnType, TypeRole.PAGE)) {
// SourcePersistentEntityCriteriaQuery<Object> count = cb.createQuery();
// count.select(cb.count(query.getRoots().iterator().next()));
// CommonAbstractCriteria countQueryCriteria = defineQuery(matchContext, matchContext.getRootEntity(), cb);
QueryModel countQuery = QueryModel.from(queryModel.getPersistentEntity());
countQuery.projections().count();
QueryModel.Junction junction = queryModel.getCriteria();
for (QueryModel.Criterion criterion : junction.getCriteria()) {
countQuery.add(criterion);
}
for (JoinPath joinPath : queryModel.getJoinPaths()) {
Join.Type joinType = joinPath.getJoinType();
switch(joinType) {
case INNER:
case FETCH:
joinType = Join.Type.DEFAULT;
break;
case LEFT_FETCH:
joinType = Join.Type.LEFT;
break;
case RIGHT_FETCH:
joinType = Join.Type.RIGHT;
break;
default:
}
countQuery.join(joinPath.getPath(), joinType, null);
}
countQueryResult = queryBuilder.buildQuery(countQuery);
}
return new MethodMatchInfo(DataMethod.OperationType.QUERY, resultType, getInterceptorElement(matchContext, interceptorType)).dto(isDto).optimisticLock(optimisticLock).queryResult(queryResult).countQueryResult(countQueryResult);
}
Aggregations