Example usage for javax.persistence EntityManager getMetamodel

List of usage examples for javax.persistence EntityManager getMetamodel

Introduction

In this page you can find the example usage for javax.persistence EntityManager getMetamodel.

Prototype

public Metamodel getMetamodel();

Source Link

Document

Return an instance of Metamodel interface for access to the metamodel of the persistence unit.

Usage

From source file:org.gvnix.web.datatables.util.impl.DatatablesUtilsBeanImpl.java

/**
 * {@inheritDoc}//from  ww  w  . j  a  va2s  . com
 */
@Override
public <T, E extends Comparable<?>> SearchResults<T> findByCriteria(PathBuilder<T> entity,
        Map<String, List<String>> filterByAssociations, Map<String, List<String>> orderByAssociations,
        DatatablesCriterias datatablesCriterias, BooleanBuilder basePredicate, boolean distinct,
        Object[] rowsOnTopIds) throws IllegalArgumentException {
    // Check arguments aren't null
    EntityManager entityManager = entityManagerProvider.getEntityManager(entity.getType());
    Assert.notNull(entityManager);
    Assert.notNull(datatablesCriterias);

    // If null, create empty Map to avoid control code overload
    if (CollectionUtils.isEmpty(filterByAssociations)) {
        filterByAssociations = new HashMap<String, List<String>>();
    }
    if (CollectionUtils.isEmpty(orderByAssociations)) {
        orderByAssociations = new HashMap<String, List<String>>();
    }

    // true if data results must be paginated
    boolean isPaged = datatablesCriterias.getDisplaySize() != null && datatablesCriterias.getDisplaySize() > 0;

    // true if the search must take in account all columns
    boolean findInAllColumns = StringUtils.isNotEmpty(datatablesCriterias.getSearch())
            && datatablesCriterias.hasOneFilterableColumn();

    LOGGER.debug("findByCriteria for entity '{}' (paged={} findInAllColumns={})", entity.getType(), isPaged,
            findInAllColumns);

    // ----- Create queries -----

    // query will take in account datatables search, order and paging
    // criterias
    JPAQuery query = newJPAQuery(entityManager);
    query = query.from(entity);

    // baseQuery will use base search values only in order to count
    // all for success paging
    JPAQuery baseQuery = newJPAQuery(entityManager);
    baseQuery = baseQuery.from(entity);

    // ----- Entity associations for Query JOINs, ORDER BY, ... -----

    Map<String, PathBuilder<?>> associationMap = new HashMap<String, PathBuilder<?>>();

    query = prepareQueryAssociationMap(entity, filterByAssociations, datatablesCriterias, findInAllColumns,
            query, associationMap);

    // ----- Query WHERE clauses -----

    // Filters by column. Using BooleanBuilder, a cascading builder for
    // Predicate expressions
    BooleanBuilder filtersByColumnPredicate = new BooleanBuilder();

    // Filters by table (for all columns)
    BooleanBuilder filtersByTablePredicate = new BooleanBuilder();

    try {

        // Build the filters by column expression
        if (datatablesCriterias.hasOneFilteredColumn()) {

            filtersByColumnPredicate = prepareQueryFilterPart(entity, filterByAssociations, datatablesCriterias,
                    associationMap, filtersByColumnPredicate);
        }

        // Build the query to search the given value in all columns
        filtersByTablePredicate = prepareQuerySearchPart(entity, filterByAssociations, datatablesCriterias,
                findInAllColumns, associationMap, filtersByTablePredicate);
    } catch (Exception e) {
        LOGGER.error("Exception preparing filter for entity {}", entity.getType(), e);
        SearchResults<T> searchResults = new SearchResults<T>(new ArrayList<T>(0), 0, isPaged,
                new Long(org.apache.commons.lang3.ObjectUtils
                        .defaultIfNull(datatablesCriterias.getDisplayStart(), 0)),
                new Long(org.apache.commons.lang3.ObjectUtils
                        .defaultIfNull(datatablesCriterias.getDisplaySize(), 0)),
                0);
        return searchResults;
    }

    // ----- Query ORDER BY -----

    List<OrderSpecifier<?>> orderSpecifiersList = prepareQueryOrder(entity, orderByAssociations,
            datatablesCriterias, associationMap);

    // ----- Query results paging -----

    Long offset = null;
    Long limit = null;

    if (isPaged) {
        limit = new Long(datatablesCriterias.getDisplaySize());
    }
    if (datatablesCriterias.getDisplayStart() != null && datatablesCriterias.getDisplayStart() >= 0) {
        offset = new Long(datatablesCriterias.getDisplayStart());
    }

    // ------- manage Rows-on-top ----

    List<T> firstRows = null;

    // Decrease limits if firstRowsIds is used
    if (rowsOnTopIds != null) {
        LOGGER.trace("Prepare rows on top: {}", rowsOnTopIds);

        // Coherce row-on-top ids types
        Object[] cohercedRowsOnTopId = new Object[rowsOnTopIds.length];

        EntityType<? extends T> entityMetamodel = entityManager.getMetamodel().entity(entity.getType());
        // We always have just one id. This id can be an Embedded Id
        Class<?> idType = entityMetamodel.getIdType().getJavaType();
        @SuppressWarnings("unchecked")
        SingularAttribute<? extends T, ?> idAttr = (SingularAttribute<? extends T, ?>) entityMetamodel
                .getId(idType);

        Object curId;
        for (int i = 0; i < rowsOnTopIds.length; i++) {
            curId = rowsOnTopIds[i];
            if (curId.getClass() != idType) {
                cohercedRowsOnTopId[i] = conversionService.convert(curId, idType);
            } else {
                cohercedRowsOnTopId[i] = curId;
            }
        }

        // Create expression for rows-on-top
        BooleanExpression firstRowsInExpression = querydslUtilsBean.createCollectionExpression(entity,
                idAttr.getName(), Arrays.asList(cohercedRowsOnTopId));

        LOGGER.trace("Expression for rowsOnTop: {}", firstRowsInExpression);

        // Exclude firstRows from base query
        basePredicate = basePredicate.and(firstRowsInExpression.not());

        LOGGER.trace("basePredicate to exclude rowsOnTop now is: {}", basePredicate);

        // Gets rows on top
        JPAQuery firstRowsQuery = newJPAQuery(entityManager);
        firstRowsQuery = firstRowsQuery.from(entity).where(firstRowsInExpression);

        LOGGER.trace("rowsOnTop query is: {}", firstRowsQuery);

        try {
            // TODO handle fieldSelector
            firstRows = firstRowsQuery.list(entity);
        } catch (PersistenceException exSql) {
            // Log query
            LOGGER.error("Error excecuting SQL for firstRow (sql = '{}' )", firstRowsQuery);
            throw exSql;
        }

        LOGGER.trace("Found {} rows for rowsOnTop", firstRows.size());
        // Adjust limit with rows-on-top found
        if (limit != null) {
            LOGGER.trace("Update main query limit: {} --> {}", limit, limit - firstRows.size());
            limit = limit - firstRows.size();
        }

    }

    // ----- Execute the query -----
    List<T> elements = null;

    // Compose the final query and update query var to be used to count
    // total amount of rows if needed

    if (distinct) {
        LOGGER.trace("Use distinct query!!!");
        query = query.distinct();
    }

    // Predicate for base query
    boolean hasBasePredicate = true;
    if (basePredicate == null) {
        basePredicate = new BooleanBuilder();
        hasBasePredicate = false;
    }

    // query projection to count all entities without paging
    baseQuery.where(basePredicate);

    // query projection to be used to get the results and to count filtered
    // results
    query = query.where(
            basePredicate.and(filtersByColumnPredicate.getValue()).and(filtersByTablePredicate.getValue()));

    // Calculate the total amount of rows taking in account datatables
    // search and paging criterias. When results are paginated we
    // must execute a count query, otherwise the size of matched rows List
    // is the total amount of rows
    long totalResultCount = 0;
    if (isPaged) {
        try {
            totalResultCount = query.count();
        } catch (PersistenceException exSql) {
            // Log query
            LOGGER.error("Error excecuting 'count' SQL: {}", query);
            throw exSql;
        }
    }

    if (offset == null) {
        offset = new Long(0);
    } else if (offset > totalResultCount) {
        // If offset value is bigger than total results,
        // offset needs start on 0
        offset = new Long(0);
    }

    // QueryModifiers combines limit and offset
    QueryModifiers queryModifiers = new QueryModifiers(limit, offset);
    LOGGER.trace("Set limit={} offset={}", limit, offset);

    // List ordered and paginated results. An empty list is returned for no
    // results.
    query = query.orderBy(orderSpecifiersList.toArray(new OrderSpecifier[orderSpecifiersList.size()]));

    LOGGER.debug("Execute query: {}", query);
    try {
        elements = query.restrict(queryModifiers).list(entity);
    } catch (PersistenceException exSql) {
        // Log query
        LOGGER.error("Error excecuting SQL: {}", query);
        throw exSql;
    }

    if (!isPaged) {
        totalResultCount = elements.size();
    }

    long totalBaseCount = totalResultCount;
    if (hasBasePredicate) {
        // Calculate the total amount of entities including base filters
        // only
        LOGGER.trace("Execute count query: {}", baseQuery);
        try {
            totalBaseCount = baseQuery.count();
        } catch (PersistenceException exSql) {
            // Log query
            LOGGER.error("Error excecuting 'count' SQL: {}", baseQuery);
            throw exSql;
        }
        LOGGER.trace("Found : {}", totalBaseCount);
    }

    if (firstRows != null) {
        // Adjust result with rows-on-top
        totalResultCount = totalResultCount + firstRows.size();
        totalBaseCount = totalBaseCount + firstRows.size();
        elements.addAll(0, firstRows);
    }

    // Create a new SearchResults instance
    if (limit == null) {
        limit = totalBaseCount;
    }
    SearchResults<T> searchResults = new SearchResults<T>(elements, totalResultCount, isPaged, offset, limit,
            totalBaseCount);

    LOGGER.debug("findByCriteria: return {} rows from {} (offset={} limit={})", totalResultCount,
            totalBaseCount, offset, limit);
    return searchResults;
}

From source file:org.ibankapp.base.persistence.validation.validator.UniqueValidator.java

@SuppressWarnings("unchecked")
public static <T> void validate(T bean, EntityManager em) {

    EntityInformation ei = new EntityInformation(bean.getClass(), em.getMetamodel());

    Iterable<String> idAttributeNames = ei.getIdAttributeNames();

    List<Unique> uniqueList = new ArrayList<>();

    if (bean.getClass().isAnnotationPresent(Uniques.class)) {
        Uniques uniques = bean.getClass().getAnnotation(Uniques.class);
        Collections.addAll(uniqueList, uniques.constraints());
    }//from  ww w .  j a  va  2  s. c  o m

    if (bean.getClass().isAnnotationPresent(Unique.class)) {
        uniqueList.add(bean.getClass().getAnnotation(Unique.class));
    }

    for (Unique unique : uniqueList) {

        String[] properties = unique.properties();

        CriteriaBuilder cb = em.getCriteriaBuilder();
        CriteriaQuery<?> c = cb.createQuery(bean.getClass());

        Root<?> root = c.from(bean.getClass());

        Predicate condition = cb.conjunction();

        try {

            for (String idAttributeName : idAttributeNames) {
                condition = cb.and(condition, cb.notEqual(root.get(idAttributeName),
                        PropertyUtils.getProperty(bean, idAttributeName)));
            }

            for (String property : properties) {
                condition = cb.and(condition,
                        cb.equal(root.get(property), PropertyUtils.getProperty(bean, property)));
            }
        } catch (Exception e) {
            throw new BaseException("E-BASE-000001", e.getMessage()).initCause(e);
        }

        c.where(condition);

        int count = em.createQuery(c).getResultList().size();

        if (count != 0) {
            throw new BaseException("E-BASE-000008", unique.message());
        }
    }
}

From source file:ru.savvy.jpafilterbuilder.FilterCriteriaBuilder.java

/**
 * Creates new instance. Class/*from   ww w  . j a va 2  s .  co m*/
 *
 * @param em
 * @param clazz must be JPA Entity annotated
 */
public FilterCriteriaBuilder(EntityManager em, Class<T> clazz) {
    this.clazz = clazz;
    this.cb = em.getCriteriaBuilder();
    //this.query = cb.createQuery(clazz);
    //this.root = query.from(clazz);
    this.options = EnumSet.noneOf(Option.class);
    this.pb = new PredicateBuilder(cb, options);
    this.metamodel = em.getMetamodel();
}

From source file:ru.savvy.jpafilterbuilder.FilterCriteriaBuilder.java

/**
 * Creates new instance from existing query
 *
 * @param em//w ww . j  a  v a2s. c o  m
 * @param query
 */
public FilterCriteriaBuilder(EntityManager em, CriteriaQuery<T> query) {
    this.cb = em.getCriteriaBuilder();
    this.clazz = query.getResultType();
    //this.query = query;
    this.options = EnumSet.noneOf(Option.class);
    this.pb = new PredicateBuilder(cb, options);
    this.metamodel = em.getMetamodel();
    //        Set<Root<?>> roots = query.getRoots();
    //        for (Root<?> r : roots) {
    //            if (r.getJavaType().equals(this.clazz)) {
    //                this.root = (Root<T>) r;
    //                break;
    //            }
    //        }
    //        if (this.root == null) {
    //            this.root = query.from(this.clazz);
    //        }
}