Muito raramente utilizo JPQL no meu dia-a-dia e estou com dificuldade numa query (exemplificada no Ex2):
Pelo que entendi para fazer um JOIN em JPQL basta referenciarmos a Tabela atual com o atributo que representa a outra
Ex 1: Carregar as habilitações de Tarefas para um Usuário
[list]TarefaUsuario (ManyToOne) Usuario (“TarefaUsuario possui o id do usuário”)[/list]
" SELECT DISTINCT t"
" FROM TarefaUsuario t"
" JOIN t.usuario u" // Aqui foi tranquilo, pois tenho o atributo Usuário em TarefaUsuario
" WHERE"
" u.usuarioPK = :usuarioPK"
Minha dúvida é, e quando a tabela de cima não tiver um atributo que representa a de baixo e sim o contrário? Ex2: (Onde enfrento o problema) Carregar as habilitações de Tarefas de um Grupo a qual um usuário pertence.
[list]TarefaUsuario (ManyToOne) Grupo (TarefaUsuario possui o id do Grupo)[/list] [list]Grupo (ManyToOne) GrupoUsuario (GrupoUsuario possui o id do Grupo)[/list][list] GrupoUsuario (ManyToOne) Usuario (GrupoUsuario possui o id do Usuario)[/list]
" SELECT"
" DISTINCT tru"
" FROM "
" TarefaUsuario tru"
" JOIN tru.Grupo grp"
" JOIN GrupoUsuario.grupo gus" // Problema está aqui, "grp" (Grupo) não tem o id de (GrupoUsuario) e sim o inverso (relacionamento é de baixo p/ cima)
" JOIN gus.Usuario uso"
" WHERE"
" uso.segUsuarioPK = :segUsuarioPK"
Quando Rodo a Aplicação estoura a seguinte exception = [color=red]org.hibernate.hql.ast.QuerySyntaxException: Invalid path: ‘null.grupo’[/color] - Provavelmente linha 6 do EX2
Espero que tenham entendido minha dúvida.
Desde já Agradeço…
Então cara, não rolou pq no Objeto Usuario não tenho o atributo GrupoUsuário, este é o Relacionamento;
Tabela Usuário
Não contém FK;
Tabela Grupo
Não contém FK;
Tabela GrupoUsuário
id_Usuario:FK;
id_Grupo:FK;
Tabela TarefaUsuario
id_Grupo:FK;
Esse é o Select original em Firebird (Funciona Legalzinho):
" SELECT"
" DISTINCT tru.*"
" FROM TarefaUsuario tru"
" INNER JOIN Grupo gpr"
" ON gpr.Grupo_id = tru.Grupo_id"
" INNER JOIN GrupoUsuario gu"
" ON gu.ID_Grupo = gpr.ID_Grupo"
" INNER JOIN Usuario uso"
" ON uso.Usuario_Id = gu.Usuario_Id"
" WHERE"
" tru.Status = 'ATV'"
" AND uso.Usuario_Id = :Usuario_Id"
" AND uso.Status = 'ATV'"
O engraçado é que tenho certeza que a solução é simples mais não consigo encontra-la.
Quero seguir o padrão do JPQL no meu projeto, mais é meio tenso cara.
Por isso que eu digo…
Se desconfiar de uma solução para seu problema, tente aplicar antes de duvidar da capacidade da Tecnologia que está utilizando.
Fiz exatamente como pmlm disse e funfou, na verdade havia pensado nisso como uma possível solução mas confesso que achei loucura
pois no Objeto Grupo tenho uma Lista GrupoUsuario.
Pensei: Como o Hibernate vai carregar e varrer o a lista de GrupoUsuario e buscar as referencias? Se o mapeamento estiver certinho ele faz numa boa.
Segue a Solução: 1. Mapear as duas Entidades
Na classe abaixo, adiciono o mapeamento (nessa Tabela realmente tenho o id do Grupo)[code]public class GrupoUsuario implements Serializable { @ManyToOne(fetch= FetchType.EAGER) @JoinColumns({ @JoinColumn(name = “ID_USUARIO”, referencedColumnName= “ID_USUARIO”, insertable=false, updatable=false)
})
private Usuario usuario;
Na Tabela representada abaixo não tenho o id do Grupo, porém fiz o mapeamento contrário com @OneToMany com o mappedBy (que indica o lado fraco da Entidade)public class Grupo implements Serializable {
@OneToMany(mappedBy = "Grupo")
private List<GrupoUsuario> grupoUsuarioList;
2. Acertar a linha 06 da query conforme o novo relacionamento:" SELECT"
" DISTINCT tru"
" FROM "
" TarefaUsuario tru"
" JOIN tru.grupo grp"
" JOIN grp.grupoUsuarioList gus" // Ajuste da Query chamando o Atributo @OneToMany
" JOIN gus.segUsuario uso"
" WHERE"
" uso.segUsuarioPK = :segUsuarioPK"
Olhando pelo console, a query está igualzinha a que apliquei antes com o SQL…
Aí fica uma curiosidade: Apliquei o relacionamento Bidirecional, certo? A idéia é sempre fazer isso?
Agradeço aos dois pela colaboração, me ajudaram bastante.