Search in sources :

Example 1 with NotImplementedException

use of com.peterphi.std.NotImplementedException in project stdlib by petergeneric.

the class JPAQueryBuilder method forIDs.

public void forIDs(final WebQuery original, final List<?> ids) {
    this.params.clear();
    this.generated = criteriaBuilder.createQuery();
    this.generated.distinct(false);
    if (original != null) {
        addFrom(original.constraints.subclass);
        // Re-state the order (so intra-page order is still correct, since otherwise it'll be whatever order the database decides to return)
        addOrders(original.orderings);
        // Make sure we eagerly fetch what's requested
        addExpandAndFetches(original);
        // Don't set an offset or limit when selecting specific IDs
        this.offset = null;
        this.limit = null;
    } else {
        addFrom(null);
    }
    if (root.getModel().hasSingleIdAttribute()) {
        final Class idClass = root.getModel().getIdType().getJavaType();
        final Path id = root.get(root.getModel().getId(idClass));
        generated.where(id.in(param(ids)));
    } else {
        throw new NotImplementedException("Cannot handle query by IDs with IdClass!");
    }
}
Also used : Path(javax.persistence.criteria.Path) WQPath(com.peterphi.std.guice.hibernate.webquery.impl.jpa.jpafunctions.WQPath) NotImplementedException(com.peterphi.std.NotImplementedException)

Example 2 with NotImplementedException

use of com.peterphi.std.NotImplementedException in project stdlib by petergeneric.

the class JPAQueryBuilder method createSelectIDs.

public Query createSelectIDs() {
    this.generated.distinct(true);
    // Make sure we return the results in the correct order
    generated.orderBy(orders);
    List<Selection<?>> selects = new ArrayList<>();
    if (root.getModel().hasSingleIdAttribute()) {
        selects.add(root.get(root.getModel().getId(root.getModel().getIdType().getJavaType())));
    } else
        throw new NotImplementedException("Cannot handle ID selection with IdClass!");
    for (Order order : orders) {
        selects.add(order.getExpression());
    }
    if (selects.size() == 1)
        generated.select(selects.get(0));
    else
        generated.multiselect(selects);
    final Query query = session.createQuery(generated);
    if (offset != null)
        query.getQueryOptions().setFirstRow(offset);
    if (limit != null)
        query.getQueryOptions().setMaxRows(limit);
    // Set all the parameters
    for (Map.Entry<ParameterExpression, Object> entry : this.params.entrySet()) {
        query.setParameter(entry.getKey(), entry.getValue());
    }
    return query;
}
Also used : WQOrder(com.peterphi.std.guice.restclient.jaxb.webquery.WQOrder) Order(javax.persistence.criteria.Order) Query(org.hibernate.query.Query) CriteriaQuery(javax.persistence.criteria.CriteriaQuery) WebQuery(com.peterphi.std.guice.restclient.jaxb.webquery.WebQuery) Selection(javax.persistence.criteria.Selection) NotImplementedException(com.peterphi.std.NotImplementedException) ParameterExpression(javax.persistence.criteria.ParameterExpression) ArrayList(java.util.ArrayList) HashMap(java.util.HashMap) Map(java.util.Map)

Example 3 with NotImplementedException

use of com.peterphi.std.NotImplementedException in project stdlib by petergeneric.

the class JPASearchExecutor method find.

/**
 * Execute a search, returning a ConstrainedResultSet populated with the desired data (ID or Entity) with each piece of data
 * optionally serialised using the supplied serialiser
 *
 * @param query
 * 		the query to execute (including options like offset/limit, )
 * @param strategy
 * @param serialiser
 * @param <T>
 *
 * @return
 */
public <T> ConstrainedResultSet<T> find(final QEntity entity, final WebQuery query, JPASearchStrategy strategy, Function<?, ?> serialiser) {
    final String traceOperationId = Tracing.log("WebQuery:exec", () -> query.toString());
    final HibernateSQLLogger statementLog;
    if (query.isLogSQL())
        statementLog = hibernateObserver.startSQLLogger(traceOperationId);
    else
        statementLog = null;
    try {
        // Build a view of the query based on
        JPAQueryBuilder builder = new JPAQueryBuilder(sessionFactory.getCurrentSession(), entity);
        builder.forWebQuery(query);
        // First, compute the total size if requested
        final Long total;
        if (ALWAYS_COMPUTE_SIZE || query.isComputeSize()) {
            JPAQueryBuilder countBuilder = new JPAQueryBuilder(sessionFactory.getCurrentSession(), entity);
            countBuilder.forWebQuery(query);
            total = countBuilder.selectCount();
        } else {
            total = null;
        }
        // If the auto strategy is in play, take into account what's being fetched back as well as whether there are any explicit collection joins or fetches
        if (strategy == null || strategy == JPASearchStrategy.AUTO) {
            if (StringUtils.equals(query.getFetch(), "id")) {
                strategy = JPASearchStrategy.ENTITY_WRAPPED_ID;
            } else {
                // This is necessary for correct pagination because the SQL resultset will have more than one row per entity, and our offset/limit is based on entity
                if ((query.getLimit() > 0 || query.getOffset() > 0) && (builder.hasCollectionJoin() || builder.hasCollectionFetch())) {
                    strategy = JPASearchStrategy.ID_THEN_QUERY_ENTITY;
                } else {
                    strategy = JPASearchStrategy.ENTITY;
                }
            }
        }
        List list;
        switch(strategy) {
            case ID:
                {
                    list = builder.selectIDs();
                    break;
                }
            case ENTITY_WRAPPED_ID:
                {
                    list = builder.selectIDs();
                    // Transform the IDs into entity objects with the ID field populated
                    list = (List) list.stream().map(entity::newInstanceWithId).collect(Collectors.toList());
                    break;
                }
            case ENTITY:
                {
                    // TODO could we use ScrollableResults if there are collection joins? pagination would be tricky
                    list = builder.selectEntity();
                    break;
                }
            case ID_THEN_QUERY_ENTITY:
                {
                    // First, query for the IDs (and the total results if desired)
                    list = builder.selectIDs();
                    // Now re-query to retrieve the entities
                    builder = new JPAQueryBuilder(sessionFactory.getCurrentSession(), entity);
                    builder.forIDs(query, list);
                    if (!list.isEmpty())
                        list = builder.selectEntity();
                    break;
                }
            default:
                throw new NotImplementedException("Search Strategy " + strategy + " not yet implemented");
        }
        // If a serialiser has been supplied,
        if (serialiser != null)
            list = (List) list.stream().map(serialiser).collect(Collectors.toList());
        ConstrainedResultSet resultset = new ConstrainedResultSet<>(query, list);
        if (statementLog != null && query.isLogSQL())
            resultset.setSql(statementLog.getAllStatements());
        if (total != null)
            resultset.setTotal(total);
        Tracing.logOngoing(traceOperationId, "WebQuery:exec:result", () -> "size=" + resultset.getList().size() + ", total=" + total);
        return (ConstrainedResultSet<T>) resultset;
    } finally {
        if (statementLog != null)
            statementLog.close();
    }
}
Also used : HibernateSQLLogger(com.peterphi.std.guice.hibernate.module.logging.HibernateSQLLogger) ConstrainedResultSet(com.peterphi.std.guice.hibernate.webquery.ConstrainedResultSet) NotImplementedException(com.peterphi.std.NotImplementedException) List(java.util.List)

Aggregations

NotImplementedException (com.peterphi.std.NotImplementedException)3 HibernateSQLLogger (com.peterphi.std.guice.hibernate.module.logging.HibernateSQLLogger)1 ConstrainedResultSet (com.peterphi.std.guice.hibernate.webquery.ConstrainedResultSet)1 WQPath (com.peterphi.std.guice.hibernate.webquery.impl.jpa.jpafunctions.WQPath)1 WQOrder (com.peterphi.std.guice.restclient.jaxb.webquery.WQOrder)1 WebQuery (com.peterphi.std.guice.restclient.jaxb.webquery.WebQuery)1 ArrayList (java.util.ArrayList)1 HashMap (java.util.HashMap)1 List (java.util.List)1 Map (java.util.Map)1 CriteriaQuery (javax.persistence.criteria.CriteriaQuery)1 Order (javax.persistence.criteria.Order)1 ParameterExpression (javax.persistence.criteria.ParameterExpression)1 Path (javax.persistence.criteria.Path)1 Selection (javax.persistence.criteria.Selection)1 Query (org.hibernate.query.Query)1