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

com.blazebit.persistence.criteria.impl.path.AbstractFrom Maven / Gradle / Ivy

There is a newer version: 1.6.11
Show newest version
/*
 * Copyright 2014 - 2021 Blazebit.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.blazebit.persistence.criteria.impl.path;

import com.blazebit.persistence.criteria.BlazeCollectionJoin;
import com.blazebit.persistence.criteria.BlazeFetchParent;
import com.blazebit.persistence.criteria.BlazeFrom;
import com.blazebit.persistence.criteria.BlazeJoin;
import com.blazebit.persistence.criteria.BlazeListJoin;
import com.blazebit.persistence.criteria.BlazeMapJoin;
import com.blazebit.persistence.criteria.BlazeSetJoin;
import com.blazebit.persistence.criteria.impl.BlazeCriteriaBuilderImpl;
import com.blazebit.persistence.criteria.impl.ParameterVisitor;
import com.blazebit.persistence.criteria.impl.RenderContext;
import com.blazebit.persistence.criteria.impl.expression.FromSelection;
import com.blazebit.persistence.criteria.impl.expression.SubqueryExpression;

import javax.persistence.criteria.Fetch;
import javax.persistence.criteria.Join;
import javax.persistence.criteria.JoinType;
import javax.persistence.criteria.Selection;
import javax.persistence.metamodel.Attribute;
import javax.persistence.metamodel.CollectionAttribute;
import javax.persistence.metamodel.EntityType;
import javax.persistence.metamodel.ListAttribute;
import javax.persistence.metamodel.ManagedType;
import javax.persistence.metamodel.MapAttribute;
import javax.persistence.metamodel.PluralAttribute;
import javax.persistence.metamodel.SetAttribute;
import javax.persistence.metamodel.SingularAttribute;
import javax.persistence.metamodel.Type;
import java.io.Serializable;
import java.util.Collection;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;

/**
 * @author Christian Beikov
 * @since 1.2.0
 */
public abstract class AbstractFrom extends AbstractPath implements BlazeFrom {

    public static final JoinType DEFAULT_JOIN_TYPE = JoinType.INNER;

    private static final long serialVersionUID = 1L;

    private AbstractFrom correlationParent;
    private JoinScope joinScope = new BasicJoinScope();

    private Set> joins;
    private Set> fetches;
    private Map, TreatedPath> treatedPaths;

    public AbstractFrom(BlazeCriteriaBuilderImpl criteriaBuilder, Class javaType) {
        this(criteriaBuilder, javaType, null);
    }

    public AbstractFrom(BlazeCriteriaBuilderImpl criteriaBuilder, Class javaType, AbstractPath pathSource) {
        super(criteriaBuilder, javaType, pathSource);
    }

    @Override
    public Selection alias(String alias) {
        return new FromSelection(this.criteriaBuilder, this, alias);
    }

    @Override
    public String getPathExpression() {
        return getAlias();
    }

    @Override
    public void renderPathExpression(RenderContext context) {
        prepareAlias(context);
        context.getBuffer().append(getAlias());
    }

    @Override
    protected boolean isDereferencable() {
        return true;
    }

    public void visit(ParameterVisitor visitor) {
        for (AbstractJoin j : joins) {
            j.visit(visitor);
        }
    }

    @Override
    public void prepareAlias(RenderContext context) {
        if (getAlias() == null) {
            if (isCorrelated()) {
                setAlias(getCorrelationParent().getAlias());
            } else if (getJavaType() == null) {
                setAlias(context.generateAlias(((EntityType) getManagedType()).getName()));
            } else {
                setAlias(context.generateAlias(getJavaType()));
            }
        }
    }

    @Override
    public void render(RenderContext context) {
        prepareAlias(context);
        context.getBuffer().append(getAlias());
    }

    @Override
    public Attribute getAttribute() {
        return null;
    }

    public BlazeFetchParent getParent() {
        return null;
    }

    @Override
    @SuppressWarnings({"unchecked"})
    protected Attribute findAttribute(String name) {
        return (Attribute) getManagedType().getAttribute(name);
    }

    @SuppressWarnings({"unchecked"})
    protected ManagedType getManagedType() {
        return (ManagedType) getModel();
    }

    @Override
    public boolean isCorrelated() {
        return correlationParent != null;
    }

    @Override
    public AbstractFrom getCorrelationParent() {
        if (correlationParent == null) {
            throw new IllegalStateException("This from node has no correlation parent!");
        }
        return correlationParent;
    }

    @SuppressWarnings({"unchecked"})
    public AbstractFrom correlateTo(SubqueryExpression subquery) {
        final AbstractFrom correlationDelegate = createCorrelationDelegate();
        correlationDelegate.prepareCorrelationDelegate(this);
        return correlationDelegate;
    }

    protected abstract AbstractFrom createCorrelationDelegate();

    public void prepareCorrelationDelegate(AbstractFrom parent) {
        this.joinScope = new CorrelationJoinScope();
        this.correlationParent = parent;
    }

    @Override
    public String getAlias() {
        return isCorrelated() ? getCorrelationParent().getAlias() : super.getAlias();
    }

    @Override
    public abstract  AbstractFrom treatAs(Class treatAsType);

    @SuppressWarnings("unchecked")
    protected final > T addTreatedPath(T treatedPath) {
        if (treatedPaths == null) {
            treatedPaths = new LinkedHashMap<>();
        }
        T realJoin = (T) treatedPaths.get(treatedPath.getTreatType());
        if (realJoin == null) {
            realJoin = treatedPath;
            treatedPaths.put(treatedPath.getTreatType(), treatedPath);
        }
        return realJoin;
    }

    public Collection> getTreatedPaths() {
        if (treatedPaths == null) {
            return Collections.emptyList();
        }
        return treatedPaths.values();
    }

    /***************************************************
     * Joins
     ****************************************************/

    protected abstract boolean isJoinAllowed();

    protected JoinScope getJoinScope() {
        return joinScope;
    }

    protected void checkJoinAllowed() {
        if (!isJoinAllowed()) {
            throw new IllegalArgumentException("Joins on '" + getPathExpression() + "' are not allowed");
        }
    }

    private void checkJoin(Attribute attribute, JoinType jt) {
        checkJoinAllowed();
        if (jt == JoinType.RIGHT) {
            throw new UnsupportedOperationException("RIGHT JOIN not supported");
        }

        ManagedType t = getManagedType();
        if (t == null) {
            throw new IllegalArgumentException("Joins on '" + getPathExpression() + "' are not allowed");
        }
        // getAttribute will throw an exception if the attribute does not exist
        if (t.getAttribute(attribute.getName()) == null) {
            // Some old hibernate versions don't throw an exception but return null
            throw new IllegalArgumentException("Could not resolve attribute named: " + attribute.getName());
        }
    }

    @Override
    @SuppressWarnings({"unchecked"})
    public Set> getJoins() {
        return joins == null ? Collections.EMPTY_SET : (Set>) (Set) joins;
    }

    @Override
    @SuppressWarnings({"unchecked"})
    public Set> getBlazeJoins() {
        return joins == null ? Collections.EMPTY_SET : (Set>) (Set) joins;
    }

    @Override
    public  BlazeJoin join(SingularAttribute singularAttribute, String alias) {
        return join(singularAttribute, alias, DEFAULT_JOIN_TYPE);
    }

    @Override
    public  BlazeJoin join(SingularAttribute attribute, String alias, JoinType jt) {
        AbstractJoin join = constructJoin(attribute, alias, jt);
        joinScope.addJoin(join);
        return join;
    }

    private  AbstractJoin constructJoin(SingularAttribute attribute, String alias, JoinType jt) {
        if (Type.PersistenceType.BASIC.equals(attribute.getType().getPersistenceType())) {
            throw new IllegalArgumentException("Cannot join to attribute of basic type: " + attribute.getJavaType().getName());
        }

        checkJoin(attribute, jt);
        final Class attributeType = attribute.getBindableJavaType();
        SingularAttributeJoin join = new SingularAttributeJoin(criteriaBuilder, attributeType, this, attribute, jt);
        join.setAlias(alias);
        return join;
    }

    @Override
    public  BlazeCollectionJoin join(CollectionAttribute collection, String alias) {
        return join(collection, alias, DEFAULT_JOIN_TYPE);
    }

    @Override
    public  BlazeCollectionJoin join(CollectionAttribute collection, String alias, JoinType jt) {
        final CollectionAttributeJoin join = constructJoin(collection, alias, jt);
        joinScope.addJoin(join);
        return join;
    }

    private  CollectionAttributeJoin constructJoin(CollectionAttribute collection, String alias, JoinType jt) {
        checkJoin(collection, jt);
        final Class attributeType = collection.getBindableJavaType();
        CollectionAttributeJoin join = new CollectionAttributeJoin(criteriaBuilder, attributeType, this, collection, jt);
        join.setAlias(alias);
        return join;
    }

    @Override
    public  BlazeSetJoin join(SetAttribute set, String alias) {
        return join(set, alias, DEFAULT_JOIN_TYPE);
    }

    @Override
    public  BlazeSetJoin join(SetAttribute set, String alias, JoinType jt) {
        final SetAttributeJoin join = constructJoin(set, alias, jt);
        joinScope.addJoin(join);
        return join;
    }

    private  SetAttributeJoin constructJoin(SetAttribute set, String alias, JoinType jt) {
        checkJoin(set, jt);
        final Class attributeType = set.getBindableJavaType();
        SetAttributeJoin join = new SetAttributeJoin(criteriaBuilder, attributeType, this, set, jt);
        join.setAlias(alias);
        return join;
    }

    @Override
    public  BlazeListJoin join(ListAttribute list, String alias) {
        return join(list, alias, DEFAULT_JOIN_TYPE);
    }

    @Override
    public  BlazeListJoin join(ListAttribute list, String alias, JoinType jt) {
        final ListAttributeJoin join = constructJoin(list, alias, jt);
        joinScope.addJoin(join);
        return join;
    }

    private  ListAttributeJoin constructJoin(ListAttribute list, String alias, JoinType jt) {
        checkJoin(list, jt);
        final Class attributeType = list.getBindableJavaType();
        ListAttributeJoin join = new ListAttributeJoin(criteriaBuilder, attributeType, this, list, jt);
        join.setAlias(alias);
        return join;
    }

    @Override
    public  BlazeMapJoin join(MapAttribute map, String alias) {
        return join(map, alias, DEFAULT_JOIN_TYPE);
    }

    @Override
    public  BlazeMapJoin join(MapAttribute map, String alias, JoinType jt) {
        final MapAttributeJoin join = constructJoin(map, alias, jt);
        joinScope.addJoin(join);
        return join;
    }

    private  MapAttributeJoin constructJoin(MapAttribute map, String alias, JoinType jt) {
        checkJoin(map, jt);
        final Class attributeType = map.getBindableJavaType();
        MapAttributeJoin join = new MapAttributeJoin(criteriaBuilder, attributeType, this, map, jt);
        join.setAlias(alias);
        return join;
    }

    @Override
    public  BlazeJoin join(String attributeName, String alias) {
        return join(attributeName, alias, DEFAULT_JOIN_TYPE);
    }

    @Override
    @SuppressWarnings({"unchecked"})
    public  BlazeJoin join(String attributeName, String alias, JoinType jt) {
        checkJoinAllowed();
        if (jt == JoinType.RIGHT) {
            throw new UnsupportedOperationException("RIGHT JOIN not supported");
        }

        final Attribute attribute = (Attribute) getAttribute(attributeName);
        if (attribute.isCollection()) {
            final PluralAttribute pluralAttribute = (PluralAttribute) attribute;
            if (PluralAttribute.CollectionType.COLLECTION.equals(pluralAttribute.getCollectionType())) {
                return (BlazeJoin) join((CollectionAttribute) attribute, alias, jt);
            } else if (PluralAttribute.CollectionType.LIST.equals(pluralAttribute.getCollectionType())) {
                return (BlazeJoin) join((ListAttribute) attribute, alias, jt);
            } else if (PluralAttribute.CollectionType.SET.equals(pluralAttribute.getCollectionType())) {
                return (BlazeJoin) join((SetAttribute) attribute, alias, jt);
            } else {
                return (BlazeJoin) join((MapAttribute) attribute, alias, jt);
            }
        } else {
            return (BlazeJoin) join((SingularAttribute) attribute, alias, jt);
        }
    }

    @Override
    public  BlazeCollectionJoin joinCollection(String attributeName, String alias) {
        return joinCollection(attributeName, alias, DEFAULT_JOIN_TYPE);
    }

    @Override
    @SuppressWarnings({"unchecked"})
    public  BlazeCollectionJoin joinCollection(String attributeName, String alias, JoinType jt) {
        final Attribute attribute = (Attribute) getAttribute(attributeName);
        if (!attribute.isCollection()) {
            throw new IllegalArgumentException("Requested attribute was not a collection");
        }

        final PluralAttribute pluralAttribute = (PluralAttribute) attribute;
        if (!PluralAttribute.CollectionType.COLLECTION.equals(pluralAttribute.getCollectionType())) {
            throw new IllegalArgumentException("Requested attribute was not a collection");
        }

        return (BlazeCollectionJoin) join((CollectionAttribute) attribute, alias, jt);
    }

    @Override
    public  BlazeSetJoin joinSet(String attributeName, String alias) {
        return joinSet(attributeName, alias, DEFAULT_JOIN_TYPE);
    }

    @Override
    @SuppressWarnings({"unchecked"})
    public  BlazeSetJoin joinSet(String attributeName, String alias, JoinType jt) {
        final Attribute attribute = (Attribute) getAttribute(attributeName);
        if (!attribute.isCollection()) {
            throw new IllegalArgumentException("Requested attribute was not a set");
        }

        final PluralAttribute pluralAttribute = (PluralAttribute) attribute;
        if (!PluralAttribute.CollectionType.SET.equals(pluralAttribute.getCollectionType())) {
            throw new IllegalArgumentException("Requested attribute was not a set");
        }

        return (BlazeSetJoin) join((SetAttribute) attribute, alias, jt);
    }

    @Override
    public  BlazeListJoin joinList(String attributeName, String alias) {
        return joinList(attributeName, alias, DEFAULT_JOIN_TYPE);
    }

    @Override
    @SuppressWarnings({"unchecked"})
    public  BlazeListJoin joinList(String attributeName, String alias, JoinType jt) {
        final Attribute attribute = (Attribute) getAttribute(attributeName);
        if (!attribute.isCollection()) {
            throw new IllegalArgumentException("Requested attribute was not a list");
        }

        final PluralAttribute pluralAttribute = (PluralAttribute) attribute;
        if (!PluralAttribute.CollectionType.LIST.equals(pluralAttribute.getCollectionType())) {
            throw new IllegalArgumentException("Requested attribute was not a list");
        }

        return (BlazeListJoin) join((ListAttribute) attribute, alias, jt);
    }

    @Override
    public  BlazeMapJoin joinMap(String attributeName, String alias) {
        return joinMap(attributeName, alias, DEFAULT_JOIN_TYPE);
    }

    @Override
    @SuppressWarnings({"unchecked"})
    public  BlazeMapJoin joinMap(String attributeName, String alias, JoinType jt) {
        final Attribute attribute = (Attribute) getAttribute(attributeName);
        if (!attribute.isCollection()) {
            throw new IllegalArgumentException("Requested attribute was not a map");
        }

        final PluralAttribute pluralAttribute = (PluralAttribute) attribute;
        if (!PluralAttribute.CollectionType.MAP.equals(pluralAttribute.getCollectionType())) {
            throw new IllegalArgumentException("Requested attribute was not a map");
        }

        return (BlazeMapJoin) join((MapAttribute) attribute, alias, jt);
    }

    @Override
    public  BlazeJoin join(EntityType entityType, String alias) {
        return join(entityType, alias, DEFAULT_JOIN_TYPE);
    }

    @Override
    public  BlazeJoin join(Class entityTypeClass, String alias) {
        return join(criteriaBuilder.getEntityMetamodel().entity(entityTypeClass), alias, DEFAULT_JOIN_TYPE);
    }

    @Override
    public  BlazeJoin join(EntityType entityType) {
        return join(entityType, null, DEFAULT_JOIN_TYPE);
    }

    @Override
    public  BlazeJoin join(Class entityTypeClass) {
        return join(criteriaBuilder.getEntityMetamodel().entity(entityTypeClass), null, DEFAULT_JOIN_TYPE);
    }

    @Override
    public  BlazeJoin join(EntityType entityType, JoinType joinType) {
        return join(entityType, null, joinType);
    }

    @Override
    public  BlazeJoin join(Class entityTypeClass, JoinType joinType) {
        return join(criteriaBuilder.getEntityMetamodel().entity(entityTypeClass), null, joinType);
    }

    @Override
    public  BlazeJoin join(Class entityTypeClass, String alias, JoinType joinType) {
        return join(criteriaBuilder.getEntityMetamodel().entity(entityTypeClass), alias, joinType);
    }

    @Override
    public  BlazeJoin join(EntityType entityType, String alias, JoinType joinType) {
        if (entityType == null) {
            throw new IllegalArgumentException("Null entity type");
        }
        if (joinType == null) {
            throw new IllegalArgumentException("Null join type");
        }
        EntityJoin join = new EntityJoin<>(criteriaBuilder,this, entityType, joinType);
        join.setAlias(alias);
        joinScope.addJoin(join);
        return join;
    }

    /***************************************************
     * Fetches
     ****************************************************/

    protected boolean isFetchAllowed() {
        return isJoinAllowed();
    }

    protected void checkFetchAllowed() {
        if (!isFetchAllowed()) {
            throw new IllegalArgumentException("Join fetches on '" + getPathExpression() + "' are not allowed");
        }
    }

    @Override
    @SuppressWarnings({"unchecked"})
    public Set> getFetches() {
        return fetches == null ? Collections.EMPTY_SET : (Set>) (Set) fetches;
    }

    @Override
    public  BlazeJoin fetch(SingularAttribute singularAttribute, String alias) {
        return fetch(singularAttribute, alias, DEFAULT_JOIN_TYPE);
    }

    @Override
    public  BlazeJoin fetch(SingularAttribute attribute, String alias, JoinType jt) {
        checkFetchAllowed();
        AbstractJoin fetch = constructJoin(attribute, alias, jt);
        joinScope.addFetch(fetch);
        return fetch;
    }

    @Override
    public  BlazeJoin fetch(PluralAttribute pluralAttribute, String alias) {
        return fetch(pluralAttribute, alias, DEFAULT_JOIN_TYPE);
    }

    @Override
    @SuppressWarnings({"unchecked"})
    public  BlazeJoin fetch(PluralAttribute pluralAttribute, String alias, JoinType jt) {
        checkFetchAllowed();

        final AbstractJoin fetch;
        if (PluralAttribute.CollectionType.COLLECTION.equals(pluralAttribute.getCollectionType())) {
            fetch = constructJoin((CollectionAttribute) pluralAttribute, alias, jt);
        } else if (PluralAttribute.CollectionType.LIST.equals(pluralAttribute.getCollectionType())) {
            fetch = constructJoin((ListAttribute) pluralAttribute, alias, jt);
        } else if (PluralAttribute.CollectionType.SET.equals(pluralAttribute.getCollectionType())) {
            fetch = constructJoin((SetAttribute) pluralAttribute, alias, jt);
        } else {
            fetch = constructJoin((MapAttribute) pluralAttribute, alias, jt);
        }
        joinScope.addFetch(fetch);
        return fetch;
    }

    @Override
    public  BlazeJoin fetch(String attributeName, String alias) {
        return fetch(attributeName, alias, DEFAULT_JOIN_TYPE);
    }

    @Override
    @SuppressWarnings({"unchecked"})
    public  BlazeJoin fetch(String attributeName, String alias, JoinType jt) {
        checkFetchAllowed();

        Attribute attribute = (Attribute) getAttribute(attributeName);
        if (attribute.isCollection()) {
            return (BlazeJoin) fetch((PluralAttribute) attribute, alias, jt);
        } else {
            return (BlazeJoin) fetch((SingularAttribute) attribute, alias, jt);
        }
    }
    
    /* Non-aliased joins and fetches */

    @Override
    public  BlazeJoin fetch(SingularAttribute attribute) {
        return fetch(attribute, (String) null);
    }

    @Override
    public  BlazeJoin fetch(SingularAttribute attribute, JoinType jt) {
        return fetch(attribute, null, jt);
    }

    @Override
    public  BlazeJoin fetch(PluralAttribute attribute) {
        return fetch(attribute, (String) null);
    }

    @Override
    public  BlazeJoin fetch(PluralAttribute attribute, JoinType jt) {
        return fetch(attribute, null, jt);
    }

    @Override
    public  BlazeJoin fetch(String attributeName) {
        return fetch(attributeName, (String) null);
    }

    @Override
    public  BlazeJoin fetch(String attributeName, JoinType jt) {
        return fetch(attributeName, (String) null, jt);
    }

    @Override
    public  BlazeJoin join(SingularAttribute attribute) {
        return join(attribute, (String) null);
    }

    @Override
    public  BlazeJoin join(SingularAttribute attribute, JoinType jt) {
        return join(attribute, (String) null, jt);
    }

    @Override
    public  BlazeCollectionJoin join(CollectionAttribute collection) {
        return join(collection, (String) null);
    }

    @Override
    public  BlazeSetJoin join(SetAttribute set) {
        return join(set, (String) null);
    }

    @Override
    public  BlazeListJoin join(ListAttribute list) {
        return join(list, (String) null);
    }

    @Override
    public  BlazeMapJoin join(MapAttribute map) {
        return join(map, (String) null);
    }

    @Override
    public  BlazeCollectionJoin join(CollectionAttribute collection, JoinType jt) {
        return join(collection, (String) null, jt);
    }

    @Override
    public  BlazeSetJoin join(SetAttribute set, JoinType jt) {
        return join(set, (String) null, jt);
    }

    @Override
    public  BlazeListJoin join(ListAttribute list, JoinType jt) {
        return join(list, (String) null, jt);
    }

    @Override
    public  BlazeMapJoin join(MapAttribute map, JoinType jt) {
        return join(map, (String) null, jt);
    }

    @Override
    public  BlazeJoin join(String attributeName) {
        return join(attributeName, (String) null);
    }

    @Override
    public  BlazeCollectionJoin joinCollection(String attributeName) {
        return joinCollection(attributeName, (String) null);
    }

    @Override
    public  BlazeSetJoin joinSet(String attributeName) {
        return joinSet(attributeName, (String) null);
    }

    @Override
    public  BlazeListJoin joinList(String attributeName) {
        return joinList(attributeName, (String) null);
    }

    @Override
    public  BlazeMapJoin joinMap(String attributeName) {
        return joinMap(attributeName, (String) null);
    }

    @Override
    public  BlazeJoin join(String attributeName, JoinType jt) {
        return join(attributeName, (String) null, jt);
    }

    @Override
    public  BlazeCollectionJoin joinCollection(String attributeName, JoinType jt) {
        return joinCollection(attributeName, (String) null, jt);
    }

    @Override
    public  BlazeSetJoin joinSet(String attributeName, JoinType jt) {
        return joinSet(attributeName, (String) null, jt);
    }

    @Override
    public  BlazeListJoin joinList(String attributeName, JoinType jt) {
        return joinList(attributeName, (String) null, jt);
    }

    @Override
    public  BlazeMapJoin joinMap(String attributeName, JoinType joinType) {
        return joinMap(attributeName, (String) null, joinType);
    }

    /* Join scope implementations */

    /**
     * @author Christian Beikov
     * @since 1.2.0
     */
    public static interface JoinScope extends Serializable {

        public void addJoin(AbstractJoin join);

        public void addFetch(AbstractJoin fetch);
    }

    /**
     * @author Christian Beikov
     * @since 1.2.0
     */
    protected class BasicJoinScope implements JoinScope {

        @Override
        public void addJoin(AbstractJoin join) {
            if (joins == null) {
                joins = new LinkedHashSet<>();
            }
            joins.add(join);
        }

        @Override
        public void addFetch(AbstractJoin fetch) {
            fetch.setFetch(true);
            addJoin(fetch);
            if (fetches == null) {
                fetches = new LinkedHashSet<>();
            }
            fetches.add(fetch);
        }
    }

    /**
     * @author Christian Beikov
     * @since 1.2.0
     */
    protected class CorrelationJoinScope implements JoinScope {

        @Override
        public void addJoin(AbstractJoin join) {
            if (joins == null) {
                joins = new LinkedHashSet<>();
            }
            joins.add(join);
        }

        @Override
        public void addFetch(AbstractJoin fetch) {
            throw new UnsupportedOperationException("Cannot define fetch from a subquery correlation");
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy