Solucionado (ver solução)
Solucionado
(ver solução)
20
respostas

Passando parâmetros na consulta JQPL com native query

Olá, como posso resolver o problema a seguir e eliminar um montão de strings passando parâmetros como o "asc" ou "desc" e o valor inicial e final do limit, se é que é possível, para a consulta em JQPL com native query, se não, como devo proceder?

    @Query(value = "SELECT * FROM ajax order by '%colName%' '%dir%' limit '%start%', '%end%'", 
            nativeQuery = true
    )
    List<JqueryDatatable> findByAjaxOrderBy(String colName, String dir, int start, int end);
20 respostas

Desse jeito aí, não vejo saída mesmo...

Você pode usar um método normal, escrevendo a query lá dentro.. Para minimizar os parâmetros, pode criar uma classe que possua essas informações que precisam ser colocadas na query e receber um objeto desse tipo aí.

Como tudo é parâmetro mesmo, vc não vai ter como fugir de passar eles, a ideia é apenas a minimizar a feiura :P.

solução!

Preciso saber se esta correto a forma que fiz! Se posso passar esse parâmetros em tempo de execução para a query?

é que isso tem cara de Spring Data JPA, não tem a ver especificamente com o Hibernate... Faltou vc colocar : antes dos nomes dos parâmetros.. E também associar cada parâmetro do método com o o da query. Teste e veja se da certo.

Nessa consulta esta retornando null, onde estou errando?

List<JqueryDatatable> listDt = jqueryDatatableService.searchByTermDirLimit(NOME_COLUNA, DIRECAO, INICIAR, QUANT_REGISTRO);
    @Transactional(readOnly = false)
    public List<JqueryDatatable> searchByTermDirLimit(String NOME_COLUNA, String DIRECAO, int INICIAR,
            int QUANT_REGISTRO) {
        return jqueryDatatableRepository.searchByTermDirLimit(NOME_COLUNA, DIRECAO, INICIAR, QUANT_REGISTRO);
    }
    @Query(value = "select * from ajax order by '%NOME_COLUNA%' '%DIRECAO%' limit '%INICIAR%', '%QUANT_REGISTRO%'", 
            nativeQuery = true
    )
    List<JqueryDatatable> searchByTermDirLimit(String NOME_COLUNA, String DIRECAO, int INICIAR, int QUANT_REGISTRO);

deixe a query simples, va incrementando e verifique o momento que passa a dar errado.

Null - o mesmo retorno! Tirei todos os parâmetros!

List<JqueryDatatable> listDt = jqueryDatatableService.searchByTermDirLimit();
    @Transactional(readOnly = false)
    public List<JqueryDatatable> searchByTermDirLimit() {
        return jqueryDatatableRepository.searchByTermDirLimit();
    }
    @Query(value = "select * from ajax", 
            nativeQuery = true
    )
    List<JqueryDatatable> searchByTermDirLimit();

é... não sei o que pode ser... pq o spring data jpa não retornaria nulo para uma lista e sim uma lista vazia..

Será que alguém aqui tem alguma sugestão para esse meu problema?

O erro!

cadê a linha 26 da classe JqueryDatatableService? Destaca a linha e coloca a classe toda.

A linha:

return jqueryDatatableRepository.searchByTermDirLimit();

a classe:

package br.com.augebit.contas.service;


import java.util.List;

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import br.com.augebit.contas.entity.JqueryDatatable;
import br.com.augebit.contas.repository.JqueryDatatableRepository;

@Service
@Transactional(readOnly = true, propagation = Propagation.REQUIRED)
public class JqueryDatatableService {

    private JqueryDatatableRepository jqueryDatatableRepository;

    public List<JqueryDatatable> findAll() {

        return jqueryDatatableRepository.findAll();
    }

    @Transactional(readOnly = false)
    public List<JqueryDatatable> searchByTermDirLimit() {
        return jqueryDatatableRepository.searchByTermDirLimit();
    }
}

Estava faltando eu fazer a injeção da classe do repositório" com o @Autowired

a consulta agora me retorna:

Parameter with that position [1] did not exist.

Tem uma sugestão?

Falta vc injetar o dao.. marca o atributo com @Autowired.

Fiz a injeção e mudou a mensagem de erro para:

Parameter with that position [1] did not exist

Alterei a consulta no repositório e mesmo assim, ainda continua com a mensagem!

o código da consulta:

@Query(value = "select * from ajax order by '%NOME_COLUNA' '%DIRECAO' limit '%INICIAR', '%QUANT_REGISTRO'", 
            nativeQuery = true
    )
    List<JqueryDatatable> searchByTermDirLimit(
            @Param("NOME_COLUNA") String NOME_COLUNA,
            @Param("DIRECAO") String DIRECAO, 
            @Param("INICIAR") int INICIAR, 
            @Param("QUANT_REGISTRO") int QUANT_REGISTRO);

Se puder dar uma olhada, coloquei o projeto no GitHub:

https://github.com/klermann/demoDataTableSpringDataJpa

Olá Alberto. Conseguiu fazer rodar aqui a consulta JPQL. O código ficou assim:

    @Query(value = "select * from ajax order by :NOME_COLUNA :DIRECAO limit :INICIAR, :QUANT_REGISTRO", 
            nativeQuery = true
    )
    List<JqueryDatatable> searchByTermDirLimit(
            @Param("NOME_COLUNA") String NOME_COLUNA,
            @Param("DIRECAO") String DIRECAO, 
            @Param("INICIAR") int INICIAR, 
            @Param("QUANT_REGISTRO") int QUANT_REGISTRO);

e o hibernate faz a consulta assim, QUE NÃO É A QUE EU PRECISO! Hibernate: select * from ajax order by ? ? limit ?, ?

preciso que ordene por direção e quantidade de itens por página! Tem uma dica ai por favor?

está certo. Isso é só o log.. ele não mostra os valores aplicados.

Alberto, como devo implementar esse código para o Spring Data Jpa, lembrando que faz parte do mesmo código que me ajudou a resolver acima e que o projeto esta aqui https://github.com/klermann/demoDataTableSpringDataJpa.git

PreparedStatement stmt = con.prepareStatement(sql);
        ResultSet rs = stmt.executeQuery();

        while (rs.next()) {
            JSONArray ja = new JSONArray();
            ja.put(rs.getString("id"));
            ja.put(rs.getString("engine"));
            ja.put(rs.getString("browser"));
            ja.put(rs.getString("platform"));
            ja.put(rs.getString("version"));
            ja.put(rs.getString("grade"));
            array.put(ja);
        }
        stmt.close();
        rs.close();

Um for aqui seria a solução fazendo a iteração com o objeto vindo através da consulta em JPQL?

Consegui fazer dessa maneira, não sei se é mais correta...

List<JqueryDatatable> listDt = jqueryDatatableService.searchByTermDirLimit(NOME_COLUNA, DIRECAO, INICIAR, QUANT_REGISTRO);

        for(JqueryDatatable jqueryDataTable : listDt){

            JSONArray jaObj = new JSONArray();
            jaObj.put(jqueryDataTable.getId());
            jaObj.put(jqueryDataTable.getEngine());
            jaObj.put(jqueryDataTable.getBrowser());
            jaObj.put(jqueryDataTable.getPlatform());
            jaObj.put(jqueryDataTable.getVersion());
            jaObj.put(jqueryDataTable.getGrade());

            array.put(jaObj);
        }