/**
   * Teste unitário para selecionar apenas alguns campos de uma tabela unida com 'join' usando alias
   * nos campos.
   */
  @Test
  public void testeSelectFieldsOfJoinComAlias() {
    final String sqlCerto =
        new StringBuilder()
            .append("select ")
            .append("a0.id, a0.ds_nome, a0.dt_nascimento ")
            .append("from livro as l0 ")
            .append("inner join autor a0 on ")
            .append("l0.autor_id = a0.id")
            .toString();

    SelectBuilder sqlBuilder = new SelectBuilder(Livro.class);
    sqlBuilder.select().addField(Autor.class, "a0", "id", "");
    sqlBuilder.select().addField(Autor.class, "a0", "nome", "");
    sqlBuilder.select().addField(Autor.class, "a0", "dataNascimento", "");
    sqlBuilder.fromAlias("l0");
    sqlBuilder.addJoin(Autor.class, "a0", "autor");

    String sqlGerado = sqlBuilder.buildSQL();
    System.out.println(sqlGerado);

    Assert.assertEquals(sqlCerto, sqlGerado);
  }
  @Override
  public String buildSQL() {
    final StringBuilder sql = new StringBuilder();
    sql.append(SELECT.getSQLSelectType());
    sql.append(" ");

    if (distinct) {
      sql.append(DISTINCT.getSQLSelectType());
      sql.append(" ");
    }

    boolean readFieldsOfJoins = false;
    if (select.getFields().isEmpty()) {
      readFieldsOfJoins = true;

      Class<?> superTypeClass = entityClass.getSuperclass();
      if (!(Object.class.equals(superTypeClass))) {
        addJoin(JoinBuilder.newJoin(entityClass, fromAlias));
      }
    }

    sql.append(select.buildSQL());

    if (readFieldsOfJoins) {
      for (Join j : joins) {
        if (!(sql.toString().endsWith(" "))) {
          sql.append(", ");
        }

        Select selectJoin = j.builSelect();
        sql.append(selectJoin.buildSQL());
      }
    }

    sql.append(" ");
    sql.append(FROM.getSQLSelectType());
    sql.append(" ");
    sql.append(getTableName(entityClass));

    if (fromAlias != null && !(fromAlias.isEmpty())) {
      sql.append(" " + AS.getSQLSelectType() + " " + fromAlias);
    }

    if (!joins.isEmpty()) {
      for (Join j : joins) {
        sql.append(" ");
        sql.append(j.buildSQL());
      }
    }

    if (where != null) {
      sql.append(" ");
      sql.append(WHERE.getSQLSelectType());
      sql.append(" ");
      sql.append(where.buildSQL());
    }

    if (groupBy != null) {
      sql.append(" ");
      sql.append(groupBy.buildSQL());
    }

    if (orderBy != null) {
      sql.append(" ");
      sql.append(orderBy.buildSQL());
    }

    if (offset > DEFAULT_LIMIT_AND_OFFSET) {
      sql.append(" ");
      sql.append(OFFSET.getSQLSelectType());
      sql.append(" ");
      sql.append(offset);
    }

    if (limit > DEFAULT_LIMIT_AND_OFFSET) {
      sql.append(" ");
      sql.append(LIMIT.getSQLSelectType());
      sql.append(" ");
      sql.append(limit);
    }

    if (union != null) {
      sql.append(" ");
      sql.append(unionType.getUnionType());
      sql.append(" ");
      sql.append(union.buildSQL());
    }

    return sql.toString();
  }