protected boolean isDuplicateAssociation( final Set visitedAssociationKeys, final String foreignKeyTable, final String[] foreignKeyColumns ) { //disable a join back to this same association final boolean isSameJoin = oneToManyPersister.getTableName().equals(foreignKeyTable) && Arrays.equals( foreignKeyColumns, oneToManyPersister.getKeyColumnNames() ); return isSameJoin || super.isDuplicateAssociation(visitedAssociationKeys, foreignKeyTable, foreignKeyColumns); }
/** * Should we join this association? */ protected boolean isJoinable( final int joinType, final Set visitedAssociationKeys, final String lhsTable, final String[] lhsColumnNames, final AssociationType type, final int depth ) { if (joinType<0) return false; if (joinType==JoinFragment.INNER_JOIN) return true; Integer maxFetchDepth = getFactory().getSettings().getMaximumFetchDepth(); final boolean tooDeep = maxFetchDepth!=null && depth >= maxFetchDepth.intValue(); return !tooDeep && !isDuplicateAssociation( visitedAssociationKeys, lhsTable, lhsColumnNames, type ); }
/** * Used to detect circularities in the joined graph */ protected boolean isDuplicateAssociation( final Set visitedAssociationKeys, final String lhsTable, final String[] lhsColumnNames, final AssociationType type ) { final String foreignKeyTable; final String[] foreignKeyColumns; if ( type.getForeignKeyDirection()==ForeignKeyDirection.FOREIGN_KEY_FROM_PARENT ) { foreignKeyTable = lhsTable; foreignKeyColumns = lhsColumnNames; } else { foreignKeyTable = type.getAssociatedJoinable( getFactory() ).getTableName(); foreignKeyColumns = JoinHelper.getRHSColumnNames( type, getFactory() ); } return isDuplicateAssociation(visitedAssociationKeys, foreignKeyTable, foreignKeyColumns); }
/** * Uniquely identifier a foreign key, so that we don't * join it more than once, and create circularities */ private static final class AssociationKey { private String[] columns; private String table; private AssociationKey(String[] columns, String table) { this.columns = columns; this.table = table; } public boolean equals(Object other) { AssociationKey that = (AssociationKey) other; return that.table.equals(table) && Arrays.equals(columns, that.columns); } public int hashCode() { return table.hashCode(); //TODO: inefficient } }