public void testEmployeeOuterJoinAddressPhoneProjectsTeamLeaderAddressTeamMembersPhones() {
    ReadAllQuery query = new ReadAllQuery();
    query.setReferenceClass(Employee.class);

    ReadAllQuery controlQuery = (ReadAllQuery) query.clone();

    // Note that without the following two lines address and phones are not read not for all
    // Employees:
    // once an Employee is built (without Address and Phones)
    // it's not going to be rebuilt (get Address and Phones) when it's
    // up again either as a teamLeader or teamMember.
    // That means that only Employees read first indirectly (either as teamLeaders or
    // teamMembers would've got Phones and Addresses).
    query.addJoinedAttribute(query.getExpressionBuilder().getAllowingNull("address"));
    query.addJoinedAttribute(query.getExpressionBuilder().anyOfAllowingNone("phoneNumbers"));

    Expression projects = query.getExpressionBuilder().anyOfAllowingNone("projects");
    query.addJoinedAttribute(projects);
    Expression teamLeader = projects.getAllowingNull("teamLeader");
    query.addJoinedAttribute(teamLeader);
    Expression teamLeaderAddress = teamLeader.getAllowingNull("address");
    query.addJoinedAttribute(teamLeaderAddress);
    Expression teamMembers = projects.anyOfAllowingNone("teamMembers");
    query.addJoinedAttribute(teamMembers);
    Expression teamMembersPhones = teamMembers.anyOfAllowingNone("phoneNumbers");
    query.addJoinedAttribute(teamMembersPhones);

    String errorMsg = executeQueriesAndCompareResults(controlQuery, query);
    if (errorMsg.length() > 0) {
      fail(errorMsg);
    }
  }
  public void testProjectOuterJoinTeamLeaderAddressTeamMembersAddressPhonesWhereProjectName() {
    ReadAllQuery query = new ReadAllQuery();
    query.setReferenceClass(Project.class);
    query.setSelectionCriteria(
        query
            .getExpressionBuilder()
            .get("name")
            .equal("Problem Reporting System")
            .or(query.getExpressionBuilder().get("name").equal("Bleep Blob")));

    ReadAllQuery controlQuery = (ReadAllQuery) query.clone();

    Expression teamLeader = query.getExpressionBuilder().getAllowingNull("teamLeader");
    query.addJoinedAttribute(teamLeader);
    Expression teamLeaderAddress = teamLeader.getAllowingNull("address");
    query.addJoinedAttribute(teamLeaderAddress);
    Expression teamMembers = query.getExpressionBuilder().anyOfAllowingNone("teamMembers");
    query.addJoinedAttribute(teamMembers);
    Expression teamMembersAddress = teamMembers.getAllowingNull("address");
    query.addJoinedAttribute(teamMembersAddress);
    Expression teamMembersPhones = teamMembers.anyOfAllowingNone("phoneNumbers");
    query.addJoinedAttribute(teamMembersPhones);

    String errorMsg = executeQueriesAndCompareResults(controlQuery, query);
    if (errorMsg.length() > 0) {
      fail(errorMsg);
    }
  }
  private Expression buildExpressionFrom(Expression expression) {
    String name = "";
    if (getQueryable() != null) {
      name = getQueryable().getName();
    }

    if (getQueryable() != null && !getQueryable().usesAnyOf()) {
      if (!this.allowsNull) {
        return expression.get(name);
      }
      return expression.getAllowingNull(name);
    }
    if (!this.allowsNull) {
      return expression.anyOf(name);
    }
    return expression.anyOfAllowingNone(name);
  }