Search in sources :

Example 1 with AbstractPersistentEntityCriteriaQuery

use of io.micronaut.data.model.jpa.criteria.impl.AbstractPersistentEntityCriteriaQuery in project micronaut-data by micronaut-projects.

the class FindMethodMatcher method match.

@Override
protected MethodMatch match(MethodMatchContext matchContext, java.util.regex.Matcher matcher) {
    if (isCompatibleReturnType(matchContext)) {
        return new QueryCriteriaMethodMatch(matcher) {

            boolean hasIdMatch;

            @Override
            protected <T> void apply(MethodMatchContext matchContext, PersistentEntityRoot<T> root, PersistentEntityCriteriaQuery<T> query, SourcePersistentEntityCriteriaBuilder cb) {
                super.apply(matchContext, root, query, cb);
                if (query instanceof AbstractPersistentEntityCriteriaQuery) {
                    hasIdMatch = ((AbstractPersistentEntityCriteriaQuery<T>) query).hasOnlyIdRestriction();
                }
            }

            @Override
            protected Map.Entry<ClassElement, Class<? extends DataInterceptor>> resolveReturnTypeAndInterceptor(MethodMatchContext matchContext) {
                Map.Entry<ClassElement, Class<? extends DataInterceptor>> e = super.resolveReturnTypeAndInterceptor(matchContext);
                Class<? extends DataInterceptor> interceptorType = e.getValue();
                ClassElement queryResultType = e.getKey();
                if (isFindByIdQuery(matchContext, queryResultType)) {
                    if (interceptorType == FindOneInterceptor.class) {
                        interceptorType = FindByIdInterceptor.class;
                    } else if (interceptorType == FindOneAsyncInterceptor.class) {
                        interceptorType = FindByIdAsyncInterceptor.class;
                    } else if (interceptorType == FindOneReactiveInterceptor.class) {
                        interceptorType = FindByIdReactiveInterceptor.class;
                    }
                }
                return new AbstractMap.SimpleEntry<>(queryResultType, interceptorType);
            }

            private boolean isFindByIdQuery(@NonNull MethodMatchContext matchContext, @NonNull ClassElement queryResultType) {
                return hasIdMatch && matchContext.supportsImplicitQueries() && queryResultType.getName().equals(matchContext.getRootEntity().getName()) && hasNoWhereAndJoinDeclaration(matchContext);
            }
        };
    }
    return null;
}
Also used : QueryCriteriaMethodMatch(io.micronaut.data.processor.visitors.finders.criteria.QueryCriteriaMethodMatch) DataInterceptor(io.micronaut.data.intercept.DataInterceptor) FindByIdAsyncInterceptor(io.micronaut.data.intercept.async.FindByIdAsyncInterceptor) ClassElement(io.micronaut.inject.ast.ClassElement) PersistentEntityCriteriaQuery(io.micronaut.data.model.jpa.criteria.PersistentEntityCriteriaQuery) AbstractPersistentEntityCriteriaQuery(io.micronaut.data.model.jpa.criteria.impl.AbstractPersistentEntityCriteriaQuery) SourcePersistentEntityCriteriaBuilder(io.micronaut.data.processor.model.criteria.SourcePersistentEntityCriteriaBuilder) MethodMatchContext(io.micronaut.data.processor.visitors.MethodMatchContext) PersistentEntityRoot(io.micronaut.data.model.jpa.criteria.PersistentEntityRoot) NonNull(io.micronaut.core.annotation.NonNull) AbstractPersistentEntityCriteriaQuery(io.micronaut.data.model.jpa.criteria.impl.AbstractPersistentEntityCriteriaQuery) AbstractMap(java.util.AbstractMap) Map(java.util.Map) FindOneAsyncInterceptor(io.micronaut.data.intercept.async.FindOneAsyncInterceptor)

Example 2 with AbstractPersistentEntityCriteriaQuery

use of io.micronaut.data.model.jpa.criteria.impl.AbstractPersistentEntityCriteriaQuery 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);
}
Also used : MatchFailedException(io.micronaut.data.processor.visitors.MatchFailedException) JoinPath(io.micronaut.data.model.query.JoinPath) ClassElement(io.micronaut.inject.ast.ClassElement) QueryBuilder(io.micronaut.data.model.query.builder.QueryBuilder) QueryModelPersistentEntityCriteriaQuery(io.micronaut.data.model.jpa.criteria.impl.QueryModelPersistentEntityCriteriaQuery) QueryResult(io.micronaut.data.model.query.builder.QueryResult) SourcePersistentProperty(io.micronaut.data.processor.model.SourcePersistentProperty) MethodMatchSourcePersistentEntityCriteriaBuilderImpl(io.micronaut.data.processor.model.criteria.impl.MethodMatchSourcePersistentEntityCriteriaBuilderImpl) DataInterceptor(io.micronaut.data.intercept.DataInterceptor) Join(io.micronaut.data.annotation.Join) AnnotationMetadataHierarchy(io.micronaut.data.processor.visitors.AnnotationMetadataHierarchy) QueryModel(io.micronaut.data.model.query.QueryModel) MatchFailedException(io.micronaut.data.processor.visitors.MatchFailedException) SourcePersistentEntityCriteriaQuery(io.micronaut.data.processor.model.criteria.SourcePersistentEntityCriteriaQuery) MethodMatchInfo(io.micronaut.data.processor.visitors.finders.MethodMatchInfo) Map(java.util.Map) AbstractPersistentEntityCriteriaQuery(io.micronaut.data.model.jpa.criteria.impl.AbstractPersistentEntityCriteriaQuery)

Aggregations

DataInterceptor (io.micronaut.data.intercept.DataInterceptor)2 AbstractPersistentEntityCriteriaQuery (io.micronaut.data.model.jpa.criteria.impl.AbstractPersistentEntityCriteriaQuery)2 ClassElement (io.micronaut.inject.ast.ClassElement)2 Map (java.util.Map)2 NonNull (io.micronaut.core.annotation.NonNull)1 Join (io.micronaut.data.annotation.Join)1 FindByIdAsyncInterceptor (io.micronaut.data.intercept.async.FindByIdAsyncInterceptor)1 FindOneAsyncInterceptor (io.micronaut.data.intercept.async.FindOneAsyncInterceptor)1 PersistentEntityCriteriaQuery (io.micronaut.data.model.jpa.criteria.PersistentEntityCriteriaQuery)1 PersistentEntityRoot (io.micronaut.data.model.jpa.criteria.PersistentEntityRoot)1 QueryModelPersistentEntityCriteriaQuery (io.micronaut.data.model.jpa.criteria.impl.QueryModelPersistentEntityCriteriaQuery)1 JoinPath (io.micronaut.data.model.query.JoinPath)1 QueryModel (io.micronaut.data.model.query.QueryModel)1 QueryBuilder (io.micronaut.data.model.query.builder.QueryBuilder)1 QueryResult (io.micronaut.data.model.query.builder.QueryResult)1 SourcePersistentProperty (io.micronaut.data.processor.model.SourcePersistentProperty)1 SourcePersistentEntityCriteriaBuilder (io.micronaut.data.processor.model.criteria.SourcePersistentEntityCriteriaBuilder)1 SourcePersistentEntityCriteriaQuery (io.micronaut.data.processor.model.criteria.SourcePersistentEntityCriteriaQuery)1 MethodMatchSourcePersistentEntityCriteriaBuilderImpl (io.micronaut.data.processor.model.criteria.impl.MethodMatchSourcePersistentEntityCriteriaBuilderImpl)1 AnnotationMetadataHierarchy (io.micronaut.data.processor.visitors.AnnotationMetadataHierarchy)1