/** * PUBLIC: * Specify the one-to-one mapped attribute to be optimized in this query. * The query will join the object(s) being read with the one-to-one * attribute. The difference between this and a joined attribute is that * it allows data to be retrieved based on a join, but will not populate * the joined attribute. It also allows all of the data required for the * object(s) to be read in a single query instead of (n) queries. This * should be used when the application knows that it requires the part for * all of the objects being read. This can be used only for one-to-one * mappings where the target is not the same class as the source, either * directly or through inheritance. Also two joins cannot be done to the * same class. * * <p>Note: This cannot be used for objects where it is possible not to have * a part, as these objects will be omitted from the result set, unless an * outer join is used through passing and expression using "getAllowingNull". * * <p>Example: query.addNonFetchJoinedAttribute(query.getExpressionBuilder().get("teamLeader").get("address")) * * @see #addNonFetchJoinedAttribute(Expression) */ public void addNonFetchJoinedAttribute(Expression attributeExpression) { getNonFetchJoinAttributeExpressions().add(attributeExpression); // Bug 2804042 Must un-prepare if prepared as the SQL may change. // Joined attributes are now calculated in prePrepare. setIsPrePrepared(false); }
/** * PUBLIC: * Specify the object expression to be joined in this query. * This allows the query results to be filtered based on the join to the object. * The object should define an on clause that defines the join condition. * This allows for two non-related objects to be joined. * * <p>Example: (select all employees that are a team leader)</p> * <pre> * ExpressionBuilder project = new ExpressionBuilder(Project.class); * ExpressionBuilder employee = new ExpressionBuilder(Employee.class); * ReadAllQuery query = new ReadAllQuery(Employee.class, employee); * query.addJoin(project.on(project.get("teamLeader").equal(employee))) * </pre> */ public void addNonFetchJoin(Expression target) { getNonFetchJoinAttributeExpressions().add(target); if (target.isObjectExpression() && ((ObjectExpression)target).shouldUseOuterJoin()) { this.setShouldBuildNullForNullPk(true); } // Bug 2804042 Must un-prepare if prepared as the SQL may change. // Joined attributes are now calculated in prePrepare. setIsPrePrepared(false); }
/** * PUBLIC: * Specify the object expression to be joined in this query. * This allows the query results to be filtered based on the join to the object. * The object should define an on clause that defines the join condition. * This allows for two non-related objects to be joined. * * <p>Example: (select all employees that are a team leader)</p> * <pre> * ExpressionBuilder project = new ExpressionBuilder(Project.class); * ExpressionBuilder employee = new ExpressionBuilder(Employee.class); * ReadAllQuery query = new ReadAllQuery(Employee.class, employee); * query.addJoin(project.on(project.get("teamLeader").equal(employee))) * </pre> */ public void addNonFetchJoin(Expression target) { getNonFetchJoinAttributeExpressions().add(target); if (target.isObjectExpression() && ((ObjectExpression)target).shouldUseOuterJoin()) { this.setShouldBuildNullForNullPk(true); } // Bug 2804042 Must un-prepare if prepared as the SQL may change. // Joined attributes are now calculated in prePrepare. setIsPrePrepared(false); }
/** * Return the appropriate select statement containing the fields in the table. */ protected SQLSelectStatement buildNormalSelectStatement() { // From bug 2612185 Remember the identity hashtable used in cloning the selection criteria even in the normal case // for performance, in case subqueries need it, or for order by expressions. // 2612538 - the default size of Map (32) is appropriate Map clonedExpressions = new IdentityHashMap(); SQLSelectStatement selectStatement = buildBaseSelectStatement(false, clonedExpressions); ObjectLevelReadQuery query = ((ObjectLevelReadQuery)getQuery()); // Case, normal read for branch inheritance class that reads subclasses all in its own table(s). if (getDescriptor().hasInheritance()) { getDescriptor().getInheritancePolicy().appendWithAllSubclassesExpression(selectStatement); if ((!query.isReportQuery()) && query.shouldOuterJoinSubclasses()) { selectStatement.getExpressionBuilder().setShouldUseOuterJoinForMultitableInheritance(true); } } selectStatement.setFields(getSelectionFields(selectStatement, true)); if (query.hasNonFetchJoinedAttributeExpressions()) { selectStatement.setNonSelectFields(cloneExpressions(query.getNonFetchJoinAttributeExpressions(), clonedExpressions)); } selectStatement.normalize(getSession(), getDescriptor(), clonedExpressions); // Allow for joining indexes to be computed to ensure distinct rows. if (((ObjectLevelReadQuery)getQuery()).hasJoining()) { ((ObjectLevelReadQuery)getQuery()).getJoinedAttributeManager().computeJoiningMappingIndexes(true, getSession(), 0); } return selectStatement; }
selectStatement.setNonSelectFields(cloneExpressions(query.getNonFetchJoinAttributeExpressions(), clonedExpressions));
selectStatement.setNonSelectFields(cloneExpressions(query.getNonFetchJoinAttributeExpressions(), clonedExpressions));