Search in sources :

Example 1 with QueryJoinFragment

use of org.hibernate.sql.QueryJoinFragment in project hibernate-orm by hibernate.

the class JoinSequence method toJoinFragment.

public JoinFragment toJoinFragment(Map enabledFilters, boolean includeAllSubclassJoins, boolean renderSubclassJoins, String withClauseFragment) throws MappingException {
    final QueryJoinFragment joinFragment = new QueryJoinFragment(factory.getDialect(), useThetaStyle);
    Iterator<Join> iter;
    Join first;
    Joinable last;
    if (rootJoinable != null) {
        joinFragment.addCrossJoin(rootJoinable.getTableName(), rootAlias);
        final String filterCondition = rootJoinable.filterFragment(rootAlias, enabledFilters, treatAsDeclarations);
        // JoinProcessor needs to know if the where clause fragment came from a dynamic filter or not so it
        // can put the where clause fragment in the right place in the SQL AST.   'hasFilterCondition' keeps track
        // of that fact.
        joinFragment.setHasFilterCondition(joinFragment.addCondition(filterCondition));
        addSubclassJoins(joinFragment, rootAlias, rootJoinable, true, includeAllSubclassJoins, treatAsDeclarations);
        last = rootJoinable;
    } else if (needsTableGroupJoin(joins, withClauseFragment)) {
        iter = joins.iterator();
        first = iter.next();
        final String joinString;
        switch(first.joinType) {
            case INNER_JOIN:
                joinString = " inner join ";
                break;
            case LEFT_OUTER_JOIN:
                joinString = " left outer join ";
                break;
            case RIGHT_OUTER_JOIN:
                joinString = " right outer join ";
                break;
            case FULL_JOIN:
                joinString = " full outer join ";
                break;
            default:
                throw new AssertionFailure("undefined join type");
        }
        joinFragment.addFromFragmentString(joinString);
        joinFragment.addFromFragmentString(" (");
        joinFragment.addFromFragmentString(first.joinable.getTableName());
        joinFragment.addFromFragmentString(" ");
        joinFragment.addFromFragmentString(first.getAlias());
        for (Join join : joins) {
            // Skip joining the first join node as it is contained in the subquery
            if (join != first) {
                joinFragment.addJoin(join.getJoinable().getTableName(), join.getAlias(), join.getLHSColumns(), JoinHelper.getRHSColumnNames(join.getAssociationType(), factory), join.joinType, "");
            }
            addSubclassJoins(joinFragment, join.getAlias(), join.getJoinable(), // TODO: Think about if this could be made always true
            join.joinType == JoinType.INNER_JOIN, includeAllSubclassJoins, // builds the JoinSequence for HQL joins
            treatAsDeclarations);
        }
        joinFragment.addFromFragmentString(")");
        joinFragment.addFromFragmentString(" on ");
        final String rhsAlias = first.getAlias();
        final String[] lhsColumns = first.getLHSColumns();
        final String[] rhsColumns = JoinHelper.getRHSColumnNames(first.getAssociationType(), factory);
        for (int j = 0; j < lhsColumns.length; j++) {
            joinFragment.addFromFragmentString(lhsColumns[j]);
            joinFragment.addFromFragmentString("=");
            joinFragment.addFromFragmentString(rhsAlias);
            joinFragment.addFromFragmentString(".");
            joinFragment.addFromFragmentString(rhsColumns[j]);
            if (j < lhsColumns.length - 1) {
                joinFragment.addFromFragmentString(" and ");
            }
        }
        joinFragment.addFromFragmentString(" and ");
        joinFragment.addFromFragmentString(withClauseFragment);
        return joinFragment;
    } else {
        last = null;
    }
    for (Join join : joins) {
        // technically the treatAsDeclarations should only apply to rootJoinable or to a single Join,
        // but that is not possible atm given how these JoinSequence and Join objects are built.
        // However, it is generally ok given how the HQL parser builds these JoinSequences (a HQL join
        // results in a JoinSequence with an empty rootJoinable and a single Join).  So we use that here
        // as an assumption
        final String on = join.getAssociationType().getOnCondition(join.getAlias(), factory, enabledFilters, treatAsDeclarations);
        String condition;
        if (last != null && isManyToManyRoot(last) && ((QueryableCollection) last).getElementType() == join.getAssociationType()) {
            // the current join represents the join between a many-to-many association table
            // and its "target" table.  Here we need to apply any additional filters
            // defined specifically on the many-to-many
            final String manyToManyFilter = ((QueryableCollection) last).getManyToManyFilterFragment(join.getAlias(), enabledFilters);
            condition = "".equals(manyToManyFilter) ? on : "".equals(on) ? manyToManyFilter : on + " and " + manyToManyFilter;
        } else {
            condition = on;
        }
        if (withClauseFragment != null && !isManyToManyRoot(join.joinable)) {
            condition += " and " + withClauseFragment;
        }
        joinFragment.addJoin(join.getJoinable().getTableName(), join.getAlias(), join.getLHSColumns(), JoinHelper.getRHSColumnNames(join.getAssociationType(), factory), join.joinType, condition);
        if (renderSubclassJoins) {
            addSubclassJoins(joinFragment, join.getAlias(), join.getJoinable(), join.joinType == JoinType.INNER_JOIN, includeAllSubclassJoins, // builds the JoinSequence for HQL joins
            treatAsDeclarations);
        }
        last = join.getJoinable();
    }
    if (next != null) {
        joinFragment.addFragment(next.toJoinFragment(enabledFilters, includeAllSubclassJoins));
    }
    joinFragment.addCondition(conditions.toString());
    if (isFromPart) {
        joinFragment.clearWherePart();
    }
    return joinFragment;
}
Also used : AssertionFailure(org.hibernate.AssertionFailure) QueryJoinFragment(org.hibernate.sql.QueryJoinFragment) Joinable(org.hibernate.persister.entity.Joinable) QueryableCollection(org.hibernate.persister.collection.QueryableCollection)

Aggregations

AssertionFailure (org.hibernate.AssertionFailure)1 QueryableCollection (org.hibernate.persister.collection.QueryableCollection)1 Joinable (org.hibernate.persister.entity.Joinable)1 QueryJoinFragment (org.hibernate.sql.QueryJoinFragment)1