All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.blazebit.persistence.impl.EntitySelectResolveVisitor Maven / Gradle / Ivy

There is a newer version: 1.2.0-Alpha1
Show newest version
package com.blazebit.persistence.impl;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.LinkedHashSet;
import java.util.Set;
import java.util.SortedSet;
import java.util.TreeSet;

import javax.persistence.FetchType;
import javax.persistence.metamodel.Attribute;
import javax.persistence.metamodel.EntityType;
import javax.persistence.metamodel.Metamodel;

import com.blazebit.persistence.impl.expression.AggregateExpression;
import com.blazebit.persistence.impl.expression.FunctionExpression;
import com.blazebit.persistence.impl.expression.PathElementExpression;
import com.blazebit.persistence.impl.expression.PathExpression;
import com.blazebit.persistence.impl.expression.SimplePathReference;
import com.blazebit.persistence.impl.expression.VisitorAdapter;

/**
 * This visitor resolves entity references to their attributes. This is needed for entity references
 * in the select clause when used in combination with aggregate functions. We have to decompose the
 * entity and add the components to the group by because all component will end up in the select clause.
 * 
 * @author Christian Beikov
 * @since 1.0.5
 */
public class EntitySelectResolveVisitor extends VisitorAdapter {

    private final Metamodel m;
    private final Set pathExpressions;

    public EntitySelectResolveVisitor(Metamodel m) {
        this(m, new LinkedHashSet());
    }

    public EntitySelectResolveVisitor(Metamodel m, Set pathExpressions) {
        this.m = m;
        this.pathExpressions = pathExpressions;
    }

    public Set getPathExpressions() {
        return pathExpressions;
    }

    @Override
    public void visit(FunctionExpression expression) {
        if (!(expression instanceof AggregateExpression)) {
            super.visit(expression);
        }
    }

    @Override
    public void visit(PathExpression expression) {
        if (expression.getField() == null) {
            /**
             * We need to resolve entity selects because hibernate will
             * select every entity attribute. Since we need every select in
             * the group by (because of DB2) we need to resolve such entity
             * selects here
             */
            JoinNode baseNode = ((JoinNode) expression.getBaseNode());
            EntityType entityType;

            try {
                entityType = m.entity(baseNode.getPropertyClass());
            } catch (IllegalArgumentException e) {
                // ignore if the expression is not an entity
                return;
            }

            // we need to ensure a deterministic order for testing
            SortedSet> sortedAttributes = new TreeSet>(new Comparator>() {

                @Override
                public int compare(Attribute o1, Attribute o2) {
                    return o1.getName().compareTo(o2.getName());
                }

            });
            sortedAttributes.addAll(entityType.getAttributes());
            for (Attribute attr : sortedAttributes) {
                boolean resolve = false;
                if (ExpressionUtils.isAssociation(attr) && !attr.isCollection()) {
                    resolve = true;
                } else if (ExpressionUtils.getFetchType(attr) == FetchType.EAGER) {
                    if (attr.getPersistentAttributeType() == Attribute.PersistentAttributeType.ELEMENT_COLLECTION) {
                        throw new UnsupportedOperationException("Eager element collections are not supported");
                    }
                    resolve = true;
                }

                if (resolve) {
                    PathExpression attrPath = new PathExpression(new ArrayList(expression.getExpressions()));
                    attrPath.setPathReference(new SimplePathReference(baseNode, attr.getName()));
                    pathExpressions.add(attrPath);
                }
            }
        }
    }

    public void resolve(JoinNode baseNode) {

    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy