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

Query em JPQL

Pessoal, estou tendo um pouco de dificuldade com JPQL, e Hibernate em geral. Ja estou revisando os cursos que envolvem o assunto, mas enquanto isso queria poder contar com a ajuda de vocês.

Meu sistema possui Pessoas e Time, e uma associativa entre eles chamada PessoaTime, eu desejo fazer um método que vai listar todos os dados da PessoaTime(IdPessoa) que estão em um certo Time(IdTime). A query e a seguinte:

select p.nomeUsuario, pt.cargo from pessoa_time pt 
inner join Pessoa p on p.id_pessoa=pt.id_pessoa
inner join Time t on t.id_time=pt.id_time
where t.id_time=1;

Minha duvida e de como faria isso no JPQL. Ja dei inicio a construçao do meu Metodo:

public List<PessoaTime> listarParticipantes(Time time) {
        String consulta = "";
        Query query = getEm().createQuery(consulta);

        query.setParameter("pTime", time.getId());

        List<PessoaTime> participantes = query.getResultList();

        return participantes;
    }

Vou adicionar tambem as classes de Model para que possam entender melhor:

Pessoa Model:

@Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column (name = "id_Pessoa")
    private Integer id;

    @Column()
    private String nomeUsuario;

    @Column()
    private String senhaUsuario;

    @Column()
    private String nomeCompleto;

    @Column()
    private String email;

    @Column()
    private Integer idade;

    @OneToMany(mappedBy = "pessoa", cascade = CascadeType.MERGE)
    private List<PessoaTime> listaPessoaTime;

Time Model:

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column (name = "id_Time")
    private int id;

    @Column(nullable = false)
    private String nome;

    @Column(nullable = false)
    private String senhaTime;


    @OneToMany(mappedBy = "time",cascade = CascadeType.MERGE)
    private List<PessoaTime> listaPessoaTime;

PessoaTime Model:

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column (name="id_PessoaTime")
    private Integer id;

    @ManyToOne(cascade = CascadeType.MERGE)
    @JoinColumn(name="id_pessoa")
    private Pessoa pessoa;

    @ManyToOne(cascade = CascadeType.MERGE)
    @JoinColumn(name="id_time")
    private Time time;

    @Enumerated(EnumType.STRING)
    private Cargo cargo;
9 respostas
solução!
select pt from PessoaTime pt where pt.time.id = :timeId

Isso vai te dar todos os objetos PessoaTime que de um time específico.

Alberto, minha duvida seria mesmo pra fazer os inner join dessa query com JPQL, essa mais genérica eu consigo fazer sem problemas.

select p.nomeUsuario, pt.cargo from pessoa_time pt 
inner join Pessoa p on p.id_pessoa=pt.id_pessoa
inner join Time t on t.id_time=pt.id_time
where t.id_time=1;

Essa aqui, em JPQL. Onde o id_time seria um paramentro.

Vc não precisa fazer esses joins na JPQL, isso será feito para você por debaixo dos panos. Com os objetos PessoaTime na mão, basta invocar os métodos.

Utilizando essa consulta mais simples, consegui o seguinte resultado:

jul 26, 2016 8:56:55 AM com.sun.faces.application.view.FaceletViewHandlingStrategy handleRenderException
GRAVE: Error Rendering View[/perfilTime.xhtml]
javax.el.ELException: /perfilTime.xhtml @139,55 value="#{timeMB.listarParticipantes(time)}": Method not found: class br.com.arena.controller.TimeBean.listarParticipantes(null)
    at com.sun.faces.facelets.el.TagValueExpression.getValue(TagValueExpression.java:114)
    at javax.faces.component.ComponentStateHelper.eval(ComponentStateHelper.java:194)
    at javax.faces.component.ComponentStateHelper.eval(ComponentStateHelper.java:182)
    at javax.faces.component.UIData.getValue(UIData.java:732)
    at javax.faces.component.UIData.getDataModel(UIData.java:1811)
    at javax.faces.component.UIData.setRowIndexWithoutRowStatePreserved(UIData.java:484)
    at javax.faces.component.UIData.setRowIndex(UIData.java:473)
    at com.sun.faces.renderkit.html_basic.TableRenderer.encodeBegin(TableRenderer.java:81)
    at javax.faces.component.UIComponentBase.encodeBegin(UIComponentBase.java:869)
    at javax.faces.component.UIData.encodeBegin(UIData.java:1133)
    at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1854)
    at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1859)
    at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1859)
    at com.sun.faces.application.view.FaceletViewHandlingStrategy.renderView(FaceletViewHandlingStrategy.java:402)
    at com.sun.faces.application.view.MultiViewHandler.renderView(MultiViewHandler.java:131)
    at javax.faces.application.ViewHandlerWrapper.renderView(ViewHandlerWrapper.java:337)
    at com.sun.faces.lifecycle.RenderResponsePhase.execute(RenderResponsePhase.java:121)
    at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
    at com.sun.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:139)
    at javax.faces.webapp.FacesServlet.service(FacesServlet.java:647)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:292)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207)
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:212)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:141)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79)
    at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:616)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:528)
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1099)
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:670)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1520)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1476)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.lang.Thread.run(Unknown Source)

jul 26, 2016 8:56:55 AM org.apache.catalina.core.StandardWrapperValve invoke
GRAVE: Servlet.service() for servlet [Faces Servlet] in context with path [/arena] threw exception [/perfilTime.xhtml @139,55 value="#{timeMB.listarParticipantes(time)}": Method not found: class br.com.arena.controller.TimeBean.listarParticipantes(null)] with root cause
javax.el.ELException: /perfilTime.xhtml @139,55 value="#{timeMB.listarParticipantes(time)}": Method not found: class br.com.arena.controller.TimeBean.listarParticipantes(null)
    at com.sun.faces.facelets.el.TagValueExpression.getValue(TagValueExpression.java:114)
    at javax.faces.component.ComponentStateHelper.eval(ComponentStateHelper.java:194)
    at javax.faces.component.ComponentStateHelper.eval(ComponentStateHelper.java:182)
    at javax.faces.component.UIData.getValue(UIData.java:732)
    at javax.faces.component.UIData.getDataModel(UIData.java:1811)
    at javax.faces.component.UIData.setRowIndexWithoutRowStatePreserved(UIData.java:484)
    at javax.faces.component.UIData.setRowIndex(UIData.java:473)
    at com.sun.faces.renderkit.html_basic.TableRenderer.encodeBegin(TableRenderer.java:81)
    at javax.faces.component.UIComponentBase.encodeBegin(UIComponentBase.java:869)
    at javax.faces.component.UIData.encodeBegin(UIData.java:1133)
    at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1854)
    at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1859)
    at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1859)
    at com.sun.faces.application.view.FaceletViewHandlingStrategy.renderView(FaceletViewHandlingStrategy.java:402)
    at com.sun.faces.application.view.MultiViewHandler.renderView(MultiViewHandler.java:131)
    at javax.faces.application.ViewHandlerWrapper.renderView(ViewHandlerWrapper.java:337)
    at com.sun.faces.lifecycle.RenderResponsePhase.execute(RenderResponsePhase.java:121)
    at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
    at com.sun.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:139)
    at javax.faces.webapp.FacesServlet.service(FacesServlet.java:647)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:292)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207)
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:212)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:141)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79)
    at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:616)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:528)
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1099)
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:670)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1520)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1476)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.lang.Thread.run(Unknown Source)

Seguem os metodos:

PessoaTimeDAO:

public List<PessoaTime> listarParticipantes(Time time) {
        String consulta = "select pt from PessoaTime pt where pt.time.id = :timeId";
        Query query = getEm().createQuery(consulta);

        query.setParameter("timeId", time.getId());

        List<PessoaTime> participantes = query.getResultList();

        return participantes;
    }

TimeBean:

public List<PessoaTime> listarParticipantes(){
        return pessoaTimeDAO.listarParticipantes(time);
    }

listarparticipantes.xhtml:

<p:dataTable styleClass="table" var="time"
                                        value="#{timeMB.listarParticipantes(time)}">

                                        <p:column headerText="idPessoa">
                                            <h:outputText  value="{#{pessoaMB.pessoa.id}}" />
                                        </p:column>

                                        <p:column headerText="idPessoa">
                                            <h:outputText  value="{#{pessoaMB.pessoa.nomeUsuario}}" />
                                        </p:column>

                                        <p:column headerText="idPessoa">
                                            <h:outputText  value="{#{timeMB.time.nome}}" />
                                        </p:column>


                                    </p:dataTable>

Corrigindo o DataTable do listarparticipantes.xhtml:

<p:dataTable styleClass="table" var="time"
                                        value="#{timeMB.listarParticipantes()}">

                                        <p:column headerText="idPessoa">
                                            <h:outputText  value="#{pessoaMB.pessoa.nomeUsuario}" />
                                        </p:column>    

                                        <p:column headerText="idPessoa">
                                            <h:outputText  value="#{pessoaMB.pessoa.id}" />
                                        </p:column>                            

                                        <p:column headerText="timeNome">
                                            <h:outputText  value="#{timeMB.time.nome}" />
                                        </p:column>




                                    </p:dataTable>

Ele trouxe o seguinte resultado:

Apenas o timeMB.time.nome veio, os outros campos estão vazios.

Alberto, acredito que eu vou precisar criar uma ManagedBean pra associativa PessoaTime. Pelo pouco que você viu do código, acha que vai ser necessário ?

O seu método listarParticipantes não recebe como argumento um time. É exatamente a mensagem que aparece na exception:

avax.el.ELException: /perfilTime.xhtml @139,55 value="#{timeMB.listarParticipantes(time)}": Method not found: class br.com.arena.controller.TimeBean.listarParticipantes(null)

Ler as exceptions com carinho é extremamente importante.. Geralmente as mensagens são bem amigáveis e já dão boas dicas de como resolver o problema.

Eu corrigi isso, ficou assim:

<p:dataTable styleClass="table" var="time"
                                        value="#{timeMB.listarParticipantes()}">

                                        <p:column headerText="idPessoa">
                                            <h:outputText  value="#{pessoaMB.pessoa.nomeUsuario}" />
                                        </p:column>    

                                        <p:column headerText="idPessoa">
                                            <h:outputText  value="#{pessoaMB.pessoa.id}" />
                                        </p:column>                            

                                        <p:column headerText="timeNome">
                                            <h:outputText  value="#{timeMB.time.nome}" />
                                        </p:column>




                                    </p:dataTable>

Ele trouxe como resultado so o referente ao TimeMB.time.nome os outros de nomeUsuario e id estão vazios.

Fechei o tópico porque resolvi a duvida do JQPL, vou tratar dos outros problemas em outros tópicos. Obrigado.