Search in sources :

Example 1 with Sort

use of io.micronaut.data.model.Sort in project micronaut-data by micronaut-projects.

the class PreparedQueryDBOperation method attachPageable.

public <K> void attachPageable(Pageable pageable, boolean isSingleResult, RuntimePersistentEntity<K> persistentEntity, SqlQueryBuilder queryBuilder) {
    if (pageable != Pageable.UNPAGED) {
        StringBuilder added = new StringBuilder();
        Sort sort = pageable.getSort();
        if (sort.isSorted()) {
            added.append(queryBuilder.buildOrderBy(persistentEntity, sort).getQuery());
        } else if (isSqlServerWithoutOrderBy(query, dialect)) {
            // SQL server requires order by
            sort = sortById(persistentEntity);
            added.append(queryBuilder.buildOrderBy(persistentEntity, sort).getQuery());
        }
        if (isSingleResult && pageable.getOffset() > 0) {
            pageable = Pageable.from(pageable.getNumber(), 1);
        }
        added.append(queryBuilder.buildPagination(pageable).getQuery());
        int forUpdateIndex = query.lastIndexOf(SqlQueryBuilder.STANDARD_FOR_UPDATE_CLAUSE);
        if (forUpdateIndex == -1) {
            forUpdateIndex = query.lastIndexOf(SqlQueryBuilder.SQL_SERVER_FOR_UPDATE_CLAUSE);
        }
        if (forUpdateIndex > -1) {
            query = query.substring(0, forUpdateIndex) + added + query.substring(forUpdateIndex);
        } else {
            query += added;
        }
    }
}
Also used : Sort(io.micronaut.data.model.Sort)

Example 2 with Sort

use of io.micronaut.data.model.Sort 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 3 with Sort

use of io.micronaut.data.model.Sort in project micronaut-data by micronaut-projects.

the class DefaultMongoPreparedQuery method getFind.

@Override
public MongoFind getFind() {
    MongoFind find = mongoStoredQuery.getFind(preparedQuery.getContext());
    Pageable pageable = preparedQuery.getPageable();
    if (pageable != Pageable.UNPAGED) {
        MongoFindOptions findOptions = find.getOptions();
        MongoFindOptions options = findOptions == null ? new MongoFindOptions() : new MongoFindOptions(findOptions);
        options.limit(pageable.getSize()).skip((int) pageable.getOffset());
        Sort pageableSort = pageable.getSort();
        if (pageableSort.isSorted()) {
            Bson sort = pageableSort.getOrderBy().stream().map(order -> order.isAscending() ? Sorts.ascending(order.getProperty()) : Sorts.descending(order.getProperty())).collect(Collectors.collectingAndThen(Collectors.toList(), Sorts::orderBy));
            options.sort(sort);
        }
        return new MongoFind(options);
    }
    return find;
}
Also used : DelegateStoredQuery(io.micronaut.data.runtime.query.internal.DelegateStoredQuery) Sort(io.micronaut.data.model.Sort) MongoFindOptions(io.micronaut.data.mongodb.operations.options.MongoFindOptions) DefaultPreparedQuery(io.micronaut.data.runtime.query.internal.DefaultPreparedQuery) Internal(io.micronaut.core.annotation.Internal) Collectors(java.util.stream.Collectors) PreparedQuery(io.micronaut.data.model.runtime.PreparedQuery) BsonDocument(org.bson.BsonDocument) ArrayList(java.util.ArrayList) Bson(org.bson.conversions.Bson) List(java.util.List) Sorts(com.mongodb.client.model.Sorts) Pageable(io.micronaut.data.model.Pageable) RuntimePersistentEntity(io.micronaut.data.model.runtime.RuntimePersistentEntity) BsonInt32(org.bson.BsonInt32) Pageable(io.micronaut.data.model.Pageable) MongoFindOptions(io.micronaut.data.mongodb.operations.options.MongoFindOptions) Sort(io.micronaut.data.model.Sort) Bson(org.bson.conversions.Bson)

Example 4 with Sort

use of io.micronaut.data.model.Sort in project micronaut-data by micronaut-projects.

the class AbstractQueryInterceptor method getPageable.

/**
 * Resolves the {@link Pageable} for the given context.
 *
 * @param context The pageable
 * @return The pageable or null
 */
@NonNull
protected Pageable getPageable(MethodInvocationContext<?, ?> context) {
    Pageable pageable = getParameterInRole(context, TypeRole.PAGEABLE, Pageable.class).orElse(null);
    if (pageable == null) {
        Sort sort = getParameterInRole(context, TypeRole.SORT, Sort.class).orElse(null);
        if (sort != null) {
            int max = context.intValue(DataMethod.NAME, META_MEMBER_PAGE_SIZE).orElse(-1);
            int pageIndex = context.intValue(DataMethod.NAME, DataMethod.META_MEMBER_PAGE_INDEX).orElse(0);
            if (max > 0) {
                pageable = Pageable.from(pageIndex, max, sort);
            } else {
                pageable = Pageable.from(sort);
            }
        } else {
            int max = context.intValue(DataMethod.NAME, META_MEMBER_PAGE_SIZE).orElse(-1);
            if (max > -1) {
                return Pageable.from(0, max);
            }
        }
    }
    return pageable != null ? pageable : Pageable.UNPAGED;
}
Also used : Pageable(io.micronaut.data.model.Pageable) Sort(io.micronaut.data.model.Sort) NonNull(io.micronaut.core.annotation.NonNull)

Example 5 with Sort

use of io.micronaut.data.model.Sort in project micronaut-data by micronaut-projects.

the class HibernateJpaOperations method findAll.

@NonNull
@Override
public <T, R> Iterable<R> findAll(@NonNull PreparedQuery<T, R> preparedQuery) {
    return transactionOperations.executeRead(status -> {
        Session entityManager = sessionFactory.getCurrentSession();
        String queryStr = preparedQuery.getQuery();
        Pageable pageable = preparedQuery.getPageable();
        if (pageable != Pageable.UNPAGED) {
            Sort sort = pageable.getSort();
            if (sort.isSorted()) {
                queryStr += QUERY_BUILDER.buildOrderBy(queryStr, getEntity(preparedQuery.getRootEntity()), sort).getQuery();
            }
        }
        if (preparedQuery.isDtoProjection()) {
            Query<Tuple> q;
            if (preparedQuery.isNative()) {
                q = entityManager.createNativeQuery(queryStr, Tuple.class);
            } else if (queryStr.toLowerCase(Locale.ENGLISH).startsWith("select new ")) {
                Class<R> wrapperType = ReflectionUtils.getWrapperType(preparedQuery.getResultType());
                Query<R> query = entityManager.createQuery(queryStr, wrapperType);
                bindPreparedQuery(query, preparedQuery, entityManager, queryStr);
                return query.list();
            } else {
                q = entityManager.createQuery(queryStr, Tuple.class);
            }
            bindPreparedQuery(q, preparedQuery, entityManager, queryStr);
            return q.stream().map(tuple -> {
                Set<String> properties = tuple.getElements().stream().map(TupleElement::getAlias).collect(Collectors.toCollection(() -> new TreeSet<>(String.CASE_INSENSITIVE_ORDER)));
                return (new BeanIntrospectionMapper<Tuple, R>() {

                    @Override
                    public Object read(Tuple tuple1, String alias) {
                        if (!properties.contains(alias)) {
                            return null;
                        }
                        return tuple1.get(alias);
                    }

                    @Override
                    public ConversionService<?> getConversionService() {
                        return dataConversionService;
                    }
                }).map(tuple, preparedQuery.getResultType());
            }).collect(Collectors.toList());
        } else {
            Class<R> wrapperType = ReflectionUtils.getWrapperType(preparedQuery.getResultType());
            Query<R> q;
            if (preparedQuery.isNative()) {
                if (DataType.ENTITY.equals(preparedQuery.getResultDataType())) {
                    q = entityManager.createNativeQuery(queryStr, wrapperType);
                } else {
                    q = entityManager.createNativeQuery(queryStr);
                }
            } else {
                q = entityManager.createQuery(queryStr, wrapperType);
            }
            bindPreparedQuery(q, preparedQuery, entityManager, queryStr);
            return q.list();
        }
    });
}
Also used : DataType(io.micronaut.data.model.DataType) Connection(java.sql.Connection) ArrayUtils(io.micronaut.core.util.ArrayUtils) ExecutorReactiveOperations(io.micronaut.data.runtime.operations.ExecutorReactiveOperations) SubGraph(org.hibernate.graph.SubGraph) EachBean(io.micronaut.context.annotation.EachBean) StoredQuery(io.micronaut.data.model.runtime.StoredQuery) Locale(java.util.Locale) Map(java.util.Map) Query(org.hibernate.query.Query) CriteriaBuilder(javax.persistence.criteria.CriteriaBuilder) ArgumentUtils(io.micronaut.core.util.ArgumentUtils) DeleteOperation(io.micronaut.data.model.runtime.DeleteOperation) TypeHint(io.micronaut.core.annotation.TypeHint) AsyncCapableRepository(io.micronaut.data.operations.async.AsyncCapableRepository) Path(javax.persistence.criteria.Path) PersistentPropertyPath(io.micronaut.data.model.PersistentPropertyPath) JpaRepositoryOperations(io.micronaut.data.jpa.operations.JpaRepositoryOperations) CriteriaQuery(javax.persistence.criteria.CriteriaQuery) IntrospectionException(io.micronaut.core.beans.exceptions.IntrospectionException) Graph(org.hibernate.graph.Graph) Sort(io.micronaut.data.model.Sort) RuntimePersistentProperty(io.micronaut.data.model.runtime.RuntimePersistentProperty) Collection(java.util.Collection) SessionFactory(org.hibernate.SessionFactory) Set(java.util.Set) Collectors(java.util.stream.Collectors) Executors(java.util.concurrent.Executors) QueryHint(io.micronaut.data.annotation.QueryHint) PreparedQuery(io.micronaut.data.model.runtime.PreparedQuery) Serializable(java.io.Serializable) Objects(java.util.Objects) List(java.util.List) Stream(java.util.stream.Stream) EntityManagerFactory(javax.persistence.EntityManagerFactory) Order(javax.persistence.criteria.Order) Optional(java.util.Optional) TupleElement(javax.persistence.TupleElement) Named(jakarta.inject.Named) JpaQueryBuilder(io.micronaut.data.model.query.builder.jpa.JpaQueryBuilder) QueryParameterBinding(io.micronaut.data.model.runtime.QueryParameterBinding) AttributeNode(org.hibernate.graph.AttributeNode) RootGraph(org.hibernate.graph.RootGraph) Parameter(io.micronaut.context.annotation.Parameter) TransactionOperations(io.micronaut.transaction.TransactionOperations) Creator(io.micronaut.core.annotation.Creator) BeanProperty(io.micronaut.core.beans.BeanProperty) Session(org.hibernate.Session) FlushModeType(javax.persistence.FlushModeType) RuntimeEntityRegistry(io.micronaut.data.model.runtime.RuntimeEntityRegistry) HibernatePresenceCondition(io.micronaut.jdbc.spring.HibernatePresenceCondition) TreeSet(java.util.TreeSet) ArrayList(java.util.ArrayList) ApplicationContext(io.micronaut.context.ApplicationContext) Nullable(io.micronaut.core.annotation.Nullable) NativeQuery(org.hibernate.query.NativeQuery) Page(io.micronaut.data.model.Page) Pageable(io.micronaut.data.model.Pageable) ReactiveCapableRepository(io.micronaut.data.operations.reactive.ReactiveCapableRepository) ExecutorAsyncOperations(io.micronaut.data.runtime.operations.ExecutorAsyncOperations) Argument(io.micronaut.core.type.Argument) Expression(javax.persistence.criteria.Expression) ConversionService(io.micronaut.core.convert.ConversionService) BeanWrapper(io.micronaut.core.beans.BeanWrapper) ReactiveRepositoryOperations(io.micronaut.data.operations.reactive.ReactiveRepositoryOperations) Root(javax.persistence.criteria.Root) ExecutorService(java.util.concurrent.ExecutorService) Tuple(javax.persistence.Tuple) PagedQuery(io.micronaut.data.model.runtime.PagedQuery) Iterator(java.util.Iterator) DataConversionService(io.micronaut.data.runtime.convert.DataConversionService) EntityManager(javax.persistence.EntityManager) InsertBatchOperation(io.micronaut.data.model.runtime.InsertBatchOperation) ReflectionUtils(io.micronaut.core.reflect.ReflectionUtils) NonNull(io.micronaut.core.annotation.NonNull) CollectionUtils(io.micronaut.core.util.CollectionUtils) BeanIntrospection(io.micronaut.core.beans.BeanIntrospection) DeleteBatchOperation(io.micronaut.data.model.runtime.DeleteBatchOperation) InsertOperation(io.micronaut.data.model.runtime.InsertOperation) AnnotationMetadata(io.micronaut.core.annotation.AnnotationMetadata) EntityGraph(io.micronaut.data.jpa.annotation.EntityGraph) BeanIntrospectionMapper(io.micronaut.data.runtime.mapper.BeanIntrospectionMapper) RuntimePersistentEntity(io.micronaut.data.model.runtime.RuntimePersistentEntity) UpdateBatchOperation(io.micronaut.data.model.runtime.UpdateBatchOperation) UpdateOperation(io.micronaut.data.model.runtime.UpdateOperation) Collections(java.util.Collections) Type(org.hibernate.type.Type) Set(java.util.Set) TreeSet(java.util.TreeSet) StoredQuery(io.micronaut.data.model.runtime.StoredQuery) Query(org.hibernate.query.Query) CriteriaQuery(javax.persistence.criteria.CriteriaQuery) PreparedQuery(io.micronaut.data.model.runtime.PreparedQuery) NativeQuery(org.hibernate.query.NativeQuery) PagedQuery(io.micronaut.data.model.runtime.PagedQuery) Pageable(io.micronaut.data.model.Pageable) TupleElement(javax.persistence.TupleElement) ConversionService(io.micronaut.core.convert.ConversionService) DataConversionService(io.micronaut.data.runtime.convert.DataConversionService) Sort(io.micronaut.data.model.Sort) Tuple(javax.persistence.Tuple) Session(org.hibernate.Session) NonNull(io.micronaut.core.annotation.NonNull)

Aggregations

Sort (io.micronaut.data.model.Sort)12 Pageable (io.micronaut.data.model.Pageable)7 ArrayList (java.util.ArrayList)5 NonNull (io.micronaut.core.annotation.NonNull)4 PreparedQuery (io.micronaut.data.model.runtime.PreparedQuery)3 RuntimePersistentEntity (io.micronaut.data.model.runtime.RuntimePersistentEntity)3 List (java.util.List)3 Collectors (java.util.stream.Collectors)3 Sorts (com.mongodb.client.model.Sorts)2 AnnotationMetadata (io.micronaut.core.annotation.AnnotationMetadata)2 Internal (io.micronaut.core.annotation.Internal)2 PersistentPropertyPath (io.micronaut.data.model.PersistentPropertyPath)2 Map (java.util.Map)2 EntityManager (javax.persistence.EntityManager)2 CriteriaBuilder (javax.persistence.criteria.CriteriaBuilder)2 Expression (javax.persistence.criteria.Expression)2 Order (javax.persistence.criteria.Order)2 ApplicationContext (io.micronaut.context.ApplicationContext)1 EachBean (io.micronaut.context.annotation.EachBean)1 Parameter (io.micronaut.context.annotation.Parameter)1