2
respostas

Usando Select new para adicionar um parâmetro com lista

Bom dia pessoal,

estou com dificuldades para criar um objeto qualquer que tenha uma lista como um de seus atributos usando a clausula NEW da JPQL. Para ilustrar melhor segue um exemplo simples:

//Entidade Usuário
public class Usuario implements Serializable {

    private static final long serialVersionUID = 902608318899804872L;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;
    private String login;
    private String senha;

    @ManyToMany
    private List<Perfil> perfis;
}
//Entidade Perfil
public class Perfil implements Serializable{

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;
    private String descricao;
}
//Meu objeto que eu quero criar usando a clausula NEW
public class UsuarioDTO {

    private String login;
    private String senha;
    private List<Perfil> perfis;

    public UsuarioDTO() {
    }

    public UsuarioDTO(String login, String senha, List<Perfil> perfis) {
        this.login = login;
        this.senha = senha;
        this.perfis = perfis;
    }
}

Aí eu tenho um repository que tem o método que cria o objeto

public interface UsuarioRepository extends JpaRepository<Usuario, Integer> {

    @Query("select new br.com.demo.dtos.UsuarioDTO(u.login, u.senha, u.perfis) from Usuario u join fetch u.perfis")
    List<UsuarioDTO> findAllUsuarioDTO();
}

Mas infelizmente que eu chamo o método usuarioRepository.findAllUsuario() eu tenho o seguinte erro:

2018-06-05 12:49:29.457 ERROR 14692 --- [  restartedMain] o.h.hql.internal.ast.ErrorCounter        :  Unable to locate appropriate constructor on class [br.gov.ma.seap.joinfacesdemo.dtos.UsuarioDTO]. Expected arguments are: java.lang.String, java.lang.String, java.util.Collection
[cause=org.hibernate.PropertyNotFoundException: no appropriate constructor in class: br.gov.ma.seap.joinfacesdemo.dtos.UsuarioDTO]
2018-06-05 12:49:29.461 ERROR 14692 --- [  restartedMain] o.h.hql.internal.ast.ErrorCounter        :  Unable to locate appropriate constructor on class [br.gov.ma.seap.joinfacesdemo.dtos.UsuarioDTO]. Expected arguments are: java.lang.String, java.lang.String, java.util.Collection
[cause=org.hibernate.PropertyNotFoundException: no appropriate constructor in class: br.gov.ma.seap.joinfacesdemo.dtos.UsuarioDTO]

Desde já agradeço pela ajuda.

2 respostas

Olha, meu chute. Ele está procurando por um construtor que espera Collection... eu tiraria List e colocaria Collection no construtor.

Olá Alberto,

eu fiz o que vc recomendou e esse erro desapareceu, mas eu encontrei outro erro, mas esse erro de sintaxe do mysql, provavelmente eu não estou conseguindo montar a query:

Classe modificada
public class UsuarioDTO {

    private String login;
    private String senha;
    private Collection<Perfil> perfis;

    public UsuarioDTO() {
    }

    public UsuarioDTO(String login, String senha, Collection<Perfil> perfis) {
        this.login = login;
        this.senha = senha;
        this.perfis = perfis;
    }
}
// Meu repositório
@Query("select distinct new br.gov.ma.seap.joinfacesdemo.dtos.UsuarioDTO(u.login, u.senha, u.perfis) from Usuario u join u.perfis")
    List<UsuarioDTO> findAllUsuarioDTO();

E o novo erro:

2018-06-05 18:33:43.051  WARN 24809 --- [nio-8080-exec-1] o.h.engine.jdbc.spi.SqlExceptionHelper   : SQL Error: 1064, SQLState: 42000
2018-06-05 18:33:43.051 ERROR 24809 --- [nio-8080-exec-1] o.h.engine.jdbc.spi.SqlExceptionHelper   : You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'as col_2_0_ from usuario usuario0_ inner join usuario_perfis perfis1_ on usuario' at line 1

Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'as col_2_0_ from usuario usuario0_ inner join usuario_perfis perfis1_ on usuario' at line 1

Eu não estou conseguindo identificar que erro seria esse.