Problema em query EJB-QL [RESOLVIDO APÓS ANOS]

3 respostas
D

Olá pessoal,

Estou com um problema um tanto quanto estranho aqui.
Estou utilizando JPA para criar queries com o provider do Hibernate, mas por motivos de mudança no projeto, tive que mudar para a nhaca do TopLink. Ocorre que a query que fiz, e funciona perfeitamente com o Hibernate:

select c.nome, SUM(d.precoVenda * d.quantidade) from DetalhesPedido d join d.pedido pe join pe.cliente c where pe.dataPedido= ?1 group by c.nome

Não funciona nem a paulada no TopLInk. Ele acusa problema no sinal de multiplicação, como vocês podem ver abaixo:

Ocorre que não acho “googlando” quem tenha esse erro. E todos os tutoriais e livros que vi, não possuem informações sobre tal situação. Então me resta saber por vocês se alguém aqui já passou por isso.

Obrigado pela ajuda quem puder.

Abraços

3 Respostas

B

Gostaria de saber se vc resolveu esse problema ou voltaram para o hibernate
Muito obrigado.

D

brunotonet:
Gostaria de saber se vc resolveu esse problema ou voltaram para o hibernate
Muito obrigado.

Voltamos para o Hibernate, correndo. Realmente nem achamos como resolver e o pessoal do TopLink também não respondeu a nossa pergunta.
No hibernate funciona perfeitamente.

abraços

D

Vivendo e aprendendo. Hoje, batendo um papo com o Edson Gonçalves cai nesta questão do que não havia gostado no TopLink e este problema que enfrentei logo no início e eis que ele me mostra como funcionava:
http://www.oracle.com/technology/pub/articles/vasiliev-jpql.html

O tópico deste link que ensina como resolver a questão é Defining JPQL Joins, onde cito a resolução:

Unfortunately, the SUM function used in JPQL does not allow you to pass an arithmetic expression as the argument. What this means in practice is that you won't be able to pass p.price*l.quantity as the argument to the JPQL's SUM. However, there are ways to work around this issue. In the following example, you define class LineItemSum whose constructor is then used in the select list of the query, taking p.price and l.quantity as the parameters. What the LineItemSum constructor does is multiply p.price by l.quantity, saving the result to its rslt class variable. Next, you can iterate through the LineItemSum list retrieved by the query, summing the values of the LineItemSum's rslt variable. The following snippet shows how all this can be implemented in code:

package jpqlexample.servlets;
...

class LineItemSum {
       private Double price;
       private Integer quantity;
       private Double rslt;
       public LineItemSum (Double price, Integer quantity){
             this.rslt = quantity*price;
       }
       public Double getRslt () {
            return this.rslt;
       }
       public void setRslt (Double rslt) {
            this.rslt = rslt;
       }
    }
public class JpqlJoinsServlet extends HttpServlet {
    ...

    public void doGet(
        ...
        List<LineItemSum> arr = (List<LineItemSum>)em.createQuery
		    ("SELECT NEW jpqlexample.servlets.LineItemSum(p.price, l.quantity) FROM PurchaseOrder o 
			    JOIN o.orderLineItems l JOIN l.product p JOIN p.supplier s WHERE s.sup_name = 'Tortuga Trading'")
                              .getResultList(); 
        Iterator i = arr.iterator();
        LineItemSum lineItemSum;
        Double sum = 0.0;
        while (i.hasNext()) {
            lineItemSum = (LineItemSum) i.next();
            sum = sum + lineItemSum.getRslt();
        }
        out.println("The total cost of the ordered products supplied by Tortuga Trading: "+ sum + "<br/>");
    }
}

Eu poderia nem dar o crédito ao cara, mas ele é o CARA. Ficou pendente aqui e acho que muita gente pulou fora, como eu, do TopLink, que considerava com um desempenho melhor que o do Hibernate na época, por causa de um detalhe desses. Mas cá entre nós, ohh falha feia essa da JPA.

Criado 18 de outubro de 2007
Ultima resposta 22 de jan. de 2010
Respostas 3
Participantes 2