Foi criado uma anotação chamada DTOValueAsColumn, essa anotação tem como função anotar métodos e atributos com nomes de colunas de uma query;

Nessa anotação tem um atributo chamado “name” que deve receber o nome da coluna, caso não seja informado ele pega o nome do atributo ou do método para ser o nome da coluna da consulta;

Não precisa se preocupar com o cast, pois ao converter a consulta para o objeto é realizado tudo automaticamente. Inclusive é realizado cast de enum, caso o atributo ou parametro seja um enum, o dado trazido na consulta deve ser um inteiro para realizar o cast com base no ordinal do enum, ou uma string, para realizar o cast com base no name do enum;

Quando for um método anotado, o mesmo deve ter apenas um parâmetro. E se o método tiver “set”, o mesmo é removido para pegar o nome da coluna;

Exemplos de uso:

1//Atributo, usando o name da anotação para ser o nome da coluna 2DTOValueAsColumnSQL(name = "NOME") 3private String nome;
1//Atributo, sem usar o name da anotação, usa o nome do atributo como nome da coluna 2DTOValueAsColumnSQL 3private String nome;
1//Método, usando o name da anotação para ser o nome da coluna 2//Métodos anotados devem conter apenas um parâmetro 3DTOValueAsColumnSQL(name = "NOME") 4public void setNome(String nome) { 5 this.nome = nome; 6}
1//Método, sem usar o name da anotação, usa o nome do método como nome da coluna 2//caso o nome do método contenha "set", o mesmo é removido 3//Métodos anotados devem conter apenas um parâmetro 4DTOValueAsColumnSQL 5public void setNome(String nome) { 6 this.nome = nome; 7}

Visto que em alguns caso ocorre divergência entre os tidos de dados trazidos pela consulta quando executada em Oracle e executada em Firebird. Foi pensado nisso que foi adicionado que o mapeamento seja feito por métodos, assim pode executar um cast especifico sem problemas. Exemplo:

1private Integer ID; 2 3@DTOValueAsColumnSQL(name = "ID") 4public void setID(Object ID) { 5 if (ID instanceof Integer) 6 this.ID = (Integer) ID; 7 else if (ID instanceof BigDecimal) 8 this.ID = ((BigDecimal) ID).intValue(); 9}

No Firebird os campos Integer são retornados como Integer para o java, mas no oracle em alguns casos os campos Integer são retornados como BigDecimal, ai se faz necessário o uso de um cast mais especifico, como é no exemplo acima.

Convertendo query nativa para objeto

Para converter a query é simples, deve ser utilizada a classe QueryMappingUtil, nessa classe tem dois métodos estáticos:

<T> Optional<T> getObjectDTO(Query query, Class<T> tClass):

Esse método executa a query, e retorna apenas o primeiro registro convertido para objeto da classe passada como parâmetro “tClass”. Caso não retorne nenhum registro o mesmo retorna um Optiona.empty();

<T> List<T> getListDTO(Query query, Class<T> tClass):

Esse método executa a query, a cada registro que é encontrado na consulta, o mesmo é convertido para objeto da classe que foi passada como parâmetro “tClass”, e adiciona na lista para retorno, por algum problema que ocorra na conversão e retorne um objeto nulo, o mesmo não deve ser adicionado na lista;

Observação: Garantir que todos os tipos de dados dos campos estejam corretos, o sistema não para o mapeamento caso ocorra um erro no cast, o mesmo somente pula a coluna e vai para a próxima, mas exibe no log, qual foi a coluna e método/atributo da classe que deu problema na conversão;

Exemplo de uso

SQL:

1SELECT NUMERCM, 2 NOME 3 FROM CONTAMOV

Classe DTO:

1class ContaMovDTO { 2 DTOValueAsColumnSQL(name = "NUMEROCM") 3 Integer numeroCM; 4 DTOValueAsColumnSQL(name = "NOME") 5 String nome; 6}

Repositório:

1public List<ContaMovDTO> getAll() { 2 Query query = entityManager.createNativeQuery(//sql exemplo); 3 4 return QueryMappingUtil.getListDTO(query, ContaMovDTO.class); 5}