Jpql - join com relacionamento inverso [resolvido]

Pessoal, Boa Tarde!

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…

Não dá para pegar as tarefas pelo Usuário?
Tipo Usuario.GrupoUsuario.Grupo.TarefaUsuario…

SELECT   
   DISTINCT tru   
 FROM    
   Usuario.GrupoUsuario.Grupo.TarefaUsuario tru
 WHERE bla...bla...bla

Sei lá…

asandrob,

Primeiramente agradeço por responder ao tópico.

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.

Obrigado !!!

Podes ter as relações nas duas classes.

ManyToOne em uma, OneToMany na outra.

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;

@ManyToOne(fetch= FetchType.EAGER)
@JoinColumns({
    @JoinColumn(name= "ID_GRUPO", referencedColumnName="ID_GRUPO", insertable=false, updatable=false)
})
private Grupo grupo;

[/code]

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.