Search in sources :

Example 1 with PersistentEntityCriteriaDelete

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

the class AbstractSpecificationInterceptor method preparedQueryForCriteria.

protected final <E, QR> PreparedQuery<E, QR> preparedQueryForCriteria(RepositoryMethodKey methodKey, MethodInvocationContext<T, R> context, Type type) {
    Class<Object> rootEntity = getRequiredRootEntity(context);
    Pageable pageable = Pageable.UNPAGED;
    for (Object param : context.getParameterValues()) {
        if (param instanceof Pageable) {
            pageable = (Pageable) param;
            break;
        }
    }
    QueryBuilder sqlQueryBuilder = sqlQueryBuilderForRepositories.computeIfAbsent(methodKey, repositoryMethodKey -> {
        Class<QueryBuilder> builder = context.getAnnotationMetadata().classValue(RepositoryConfiguration.class, "queryBuilder").orElseThrow(() -> new IllegalStateException("Cannot determine QueryBuilder"));
        BeanIntrospection<QueryBuilder> introspection = BeanIntrospection.getIntrospection(builder);
        if (introspection.getConstructorArguments().length == 1 && introspection.getConstructorArguments()[0].getType() == AnnotationMetadata.class) {
            return introspection.instantiate(context.getAnnotationMetadata());
        }
        return introspection.instantiate();
    });
    QueryResult queryResult;
    if (type == Type.COUNT || type == Type.FIND_ALL || type == Type.FIND_ONE || type == Type.FIND_PAGE) {
        QuerySpecification<Object> specification = getQuerySpecification(context);
        PersistentEntityCriteriaQuery<Object> criteriaQuery = criteriaBuilder.createQuery();
        Root<Object> root = criteriaQuery.from(rootEntity);
        if (specification != null) {
            Predicate predicate = specification.toPredicate(root, criteriaQuery, criteriaBuilder);
            if (predicate != null) {
                criteriaQuery.where(predicate);
            }
        }
        if (type == Type.FIND_ALL) {
            for (Object param : context.getParameterValues()) {
                if (param instanceof Sort && param != pageable) {
                    Sort sort = (Sort) param;
                    if (sort.isSorted()) {
                        criteriaQuery.orderBy(getOrders(sort, root, criteriaBuilder));
                        break;
                    }
                }
            }
        } else if (type == Type.COUNT) {
            criteriaQuery.select(criteriaBuilder.count(root));
        }
        queryResult = ((QueryResultPersistentEntityCriteriaQuery) criteriaQuery).buildQuery(sqlQueryBuilder);
    } else if (type == Type.DELETE_ALL) {
        DeleteSpecification<Object> specification = getDeleteSpecification(context);
        PersistentEntityCriteriaDelete<Object> criteriaDelete = criteriaBuilder.createCriteriaDelete(rootEntity);
        Root<Object> root = criteriaDelete.from(rootEntity);
        if (specification != null) {
            Predicate predicate = specification.toPredicate(root, criteriaDelete, criteriaBuilder);
            if (predicate != null) {
                criteriaDelete.where(predicate);
            }
        }
        queryResult = ((QueryResultPersistentEntityCriteriaQuery) criteriaDelete).buildQuery(sqlQueryBuilder);
    } else if (type == Type.UPDATE_ALL) {
        UpdateSpecification<Object> specification = getUpdateSpecification(context);
        PersistentEntityCriteriaUpdate<Object> criteriaUpdate = criteriaBuilder.createCriteriaUpdate(rootEntity);
        Root<Object> root = criteriaUpdate.from(rootEntity);
        if (specification != null) {
            Predicate predicate = specification.toPredicate(root, criteriaUpdate, criteriaBuilder);
            if (predicate != null) {
                criteriaUpdate.where(predicate);
            }
        }
        queryResult = ((QueryResultPersistentEntityCriteriaQuery) criteriaUpdate).buildQuery(sqlQueryBuilder);
    } else {
        throw new IllegalStateException("Unknown criteria type: " + type);
    }
    String query = queryResult.getQuery();
    String update = queryResult.getUpdate();
    List<io.micronaut.data.model.query.builder.QueryParameterBinding> parameterBindings = queryResult.getParameterBindings();
    List<QueryParameterBinding> queryParameters = new ArrayList<>(parameterBindings.size());
    for (io.micronaut.data.model.query.builder.QueryParameterBinding p : parameterBindings) {
        queryParameters.add(new QueryResultParameterBinding(p, queryParameters));
    }
    String[] queryParts = queryParameters.stream().anyMatch(QueryParameterBinding::isExpandable) ? queryResult.getQueryParts().toArray(new String[0]) : null;
    StoredQuery<E, QR> storedQuery;
    if (type == Type.COUNT) {
        storedQuery = (StoredQuery<E, QR>) storedQueryResolver.createCountStoredQuery(context.getExecutableMethod(), DataMethod.OperationType.COUNT, context.getName(), context.getAnnotationMetadata(), rootEntity, query, queryParts, queryParameters);
    } else if (type == Type.FIND_ALL) {
        storedQuery = storedQueryResolver.createStoredQuery(context.getExecutableMethod(), DataMethod.OperationType.QUERY, context.getName(), context.getAnnotationMetadata(), rootEntity, query, null, queryParts, queryParameters, !pageable.isUnpaged(), false);
    } else {
        DataMethod.OperationType operationType;
        switch(type) {
            case COUNT:
                operationType = DataMethod.OperationType.COUNT;
                break;
            case DELETE_ALL:
                operationType = DataMethod.OperationType.DELETE;
                break;
            case UPDATE_ALL:
                operationType = DataMethod.OperationType.UPDATE;
                break;
            case FIND_ALL:
            case FIND_ONE:
            case FIND_PAGE:
                operationType = DataMethod.OperationType.QUERY;
                break;
            default:
                throw new IllegalStateException("Unknown value: " + type);
        }
        storedQuery = storedQueryResolver.createStoredQuery(context.getExecutableMethod(), operationType, context.getName(), context.getAnnotationMetadata(), rootEntity, query, update, queryParts, queryParameters, false, true);
    }
    return preparedQueryResolver.resolveQuery(context, storedQuery, pageable);
}
Also used : QueryParameterBinding(io.micronaut.data.model.runtime.QueryParameterBinding) DeleteSpecification(io.micronaut.data.repository.jpa.criteria.DeleteSpecification) AnnotationMetadata(io.micronaut.core.annotation.AnnotationMetadata) ArrayList(java.util.ArrayList) QueryBuilder(io.micronaut.data.model.query.builder.QueryBuilder) AnnotationMetadata(io.micronaut.core.annotation.AnnotationMetadata) Predicate(jakarta.persistence.criteria.Predicate) QueryResult(io.micronaut.data.model.query.builder.QueryResult) Pageable(io.micronaut.data.model.Pageable) Sort(io.micronaut.data.model.Sort) RepositoryConfiguration(io.micronaut.data.annotation.RepositoryConfiguration) Root(jakarta.persistence.criteria.Root) QueryResultPersistentEntityCriteriaQuery(io.micronaut.data.model.jpa.criteria.impl.QueryResultPersistentEntityCriteriaQuery) PersistentEntityCriteriaDelete(io.micronaut.data.model.jpa.criteria.PersistentEntityCriteriaDelete)

Example 2 with PersistentEntityCriteriaDelete

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

the class DeleteMethodMatcher method match.

@Override
public MethodMatch match(MethodMatchContext matchContext, java.util.regex.Matcher matcher) {
    ParameterElement[] parameters = matchContext.getParameters();
    boolean isSpecificDelete = matcher.group(2).endsWith("By");
    ParameterElement entityParameter = null;
    ParameterElement entitiesParameter = null;
    if (matchContext.getParametersNotInRole().size() == 1) {
        entityParameter = Arrays.stream(parameters).filter(p -> TypeUtils.isEntity(p.getGenericType())).findFirst().orElse(null);
        entitiesParameter = Arrays.stream(parameters).filter(p -> TypeUtils.isIterableOfEntity(p.getGenericType())).findFirst().orElse(null);
    }
    if (isSpecificDelete) {
        // Un-mark the entity parameter if there is a property named the same and 'By' syntax is used
        if (entityParameter != null) {
            if (matchContext.getRootEntity().getPropertyByName(getName(entityParameter)) != null) {
                entityParameter = null;
            }
        }
        if (entitiesParameter != null) {
            if (matchContext.getRootEntity().getPropertyByName(getName(entitiesParameter)) != null) {
                entitiesParameter = null;
            }
        }
    }
    if (entityParameter == null && entitiesParameter == null) {
        if (!TypeUtils.isValidBatchUpdateReturnType(matchContext.getMethodElement())) {
            return null;
        }
        return new DeleteCriteriaMethodMatch(matcher);
    }
    SourcePersistentEntity rootEntity = matchContext.getRootEntity();
    if (!rootEntity.hasIdentity() && !rootEntity.hasCompositeIdentity()) {
        throw new MatchFailedException("Delete all not supported for entities with no ID");
    }
    boolean supportedByImplicitQueries = !matcher.group(2).endsWith("By");
    boolean generateInIdList = entitiesParameter != null && !rootEntity.hasCompositeIdentity() && !(rootEntity.getIdentity() instanceof Embedded) && rootEntity.getVersion() == null;
    ParameterElement finalEntityParameter = entityParameter;
    ParameterElement finalEntitiesParameter = entitiesParameter;
    if (generateInIdList) {
        return new DeleteCriteriaMethodMatch(matcher) {

            @Override
            protected boolean supportedByImplicitQueries() {
                return supportedByImplicitQueries;
            }

            @Override
            protected <T> void applyPredicates(List<ParameterElement> parameters, PersistentEntityRoot<T> root, PersistentEntityCriteriaDelete<T> query, SourcePersistentEntityCriteriaBuilder cb) {
                Predicate restriction = query.getRestriction();
                Predicate predicate = root.id().in(cb.entityPropertyParameter(finalEntitiesParameter));
                if (restriction == null) {
                    query.where(predicate);
                } else {
                    query.where(cb.and(predicate, restriction));
                }
            }

            @Override
            protected ParameterElement getEntityParameter() {
                return finalEntityParameter;
            }

            @Override
            protected ParameterElement getEntitiesParameter() {
                return finalEntitiesParameter;
            }
        };
    }
    ParameterElement entityParam = entityParameter == null ? entitiesParameter : entityParameter;
    return new DeleteCriteriaMethodMatch(matcher) {

        @Override
        protected boolean supportedByImplicitQueries() {
            return supportedByImplicitQueries;
        }

        @Override
        protected <T> void applyPredicates(List<ParameterElement> parameters, PersistentEntityRoot<T> root, PersistentEntityCriteriaDelete<T> query, SourcePersistentEntityCriteriaBuilder cb) {
            Predicate restriction = query.getRestriction();
            Predicate predicate;
            if (rootEntity.getVersion() != null) {
                predicate = cb.and(cb.equal(root.id(), cb.entityPropertyParameter(entityParam)), cb.equal(root.version(), cb.entityPropertyParameter(entityParam)));
            } else {
                predicate = cb.equal(root.id(), cb.entityPropertyParameter(entityParam));
            }
            if (restriction == null) {
                query.where(predicate);
            } else {
                query.where(cb.and(predicate, restriction));
            }
        }

        @Override
        protected ParameterElement getEntityParameter() {
            return finalEntityParameter;
        }

        @Override
        protected ParameterElement getEntitiesParameter() {
            return finalEntitiesParameter;
        }
    };
}
Also used : SourcePersistentEntityCriteriaBuilder(io.micronaut.data.processor.model.criteria.SourcePersistentEntityCriteriaBuilder) Arrays(java.util.Arrays) Parameter(io.micronaut.context.annotation.Parameter) MatchFailedException(io.micronaut.data.processor.visitors.MatchFailedException) DeleteCriteriaMethodMatch(io.micronaut.data.processor.visitors.finders.criteria.DeleteCriteriaMethodMatch) Predicate(jakarta.persistence.criteria.Predicate) Internal(io.micronaut.core.annotation.Internal) SourcePersistentEntity(io.micronaut.data.processor.model.SourcePersistentEntity) ParameterElement(io.micronaut.inject.ast.ParameterElement) PersistentEntityRoot(io.micronaut.data.model.jpa.criteria.PersistentEntityRoot) Embedded(io.micronaut.data.model.Embedded) List(java.util.List) MethodMatchContext(io.micronaut.data.processor.visitors.MethodMatchContext) PersistentEntityCriteriaDelete(io.micronaut.data.model.jpa.criteria.PersistentEntityCriteriaDelete) Pattern(java.util.regex.Pattern) MatchFailedException(io.micronaut.data.processor.visitors.MatchFailedException) SourcePersistentEntity(io.micronaut.data.processor.model.SourcePersistentEntity) Predicate(jakarta.persistence.criteria.Predicate) SourcePersistentEntityCriteriaBuilder(io.micronaut.data.processor.model.criteria.SourcePersistentEntityCriteriaBuilder) PersistentEntityRoot(io.micronaut.data.model.jpa.criteria.PersistentEntityRoot) PersistentEntityCriteriaDelete(io.micronaut.data.model.jpa.criteria.PersistentEntityCriteriaDelete) List(java.util.List) ParameterElement(io.micronaut.inject.ast.ParameterElement) DeleteCriteriaMethodMatch(io.micronaut.data.processor.visitors.finders.criteria.DeleteCriteriaMethodMatch) Embedded(io.micronaut.data.model.Embedded)

Aggregations

PersistentEntityCriteriaDelete (io.micronaut.data.model.jpa.criteria.PersistentEntityCriteriaDelete)2 Predicate (jakarta.persistence.criteria.Predicate)2 Parameter (io.micronaut.context.annotation.Parameter)1 AnnotationMetadata (io.micronaut.core.annotation.AnnotationMetadata)1 Internal (io.micronaut.core.annotation.Internal)1 RepositoryConfiguration (io.micronaut.data.annotation.RepositoryConfiguration)1 Embedded (io.micronaut.data.model.Embedded)1 Pageable (io.micronaut.data.model.Pageable)1 Sort (io.micronaut.data.model.Sort)1 PersistentEntityRoot (io.micronaut.data.model.jpa.criteria.PersistentEntityRoot)1 QueryResultPersistentEntityCriteriaQuery (io.micronaut.data.model.jpa.criteria.impl.QueryResultPersistentEntityCriteriaQuery)1 QueryBuilder (io.micronaut.data.model.query.builder.QueryBuilder)1 QueryResult (io.micronaut.data.model.query.builder.QueryResult)1 QueryParameterBinding (io.micronaut.data.model.runtime.QueryParameterBinding)1 SourcePersistentEntity (io.micronaut.data.processor.model.SourcePersistentEntity)1 SourcePersistentEntityCriteriaBuilder (io.micronaut.data.processor.model.criteria.SourcePersistentEntityCriteriaBuilder)1 MatchFailedException (io.micronaut.data.processor.visitors.MatchFailedException)1 MethodMatchContext (io.micronaut.data.processor.visitors.MethodMatchContext)1 DeleteCriteriaMethodMatch (io.micronaut.data.processor.visitors.finders.criteria.DeleteCriteriaMethodMatch)1 DeleteSpecification (io.micronaut.data.repository.jpa.criteria.DeleteSpecification)1