Problemas para mapear n:n hibernate no EJB

Já fiz dessa maneira e funcionou mais não era no ejb
que poder me ajudar eu agradeço
abraços

Mensagem de erro:

14:00:07,565 INFO [STDOUT] 14:00:07,534 ERROR [LazyInitializationException] failed to lazily initialize a collection of role: br.com.trackbus.entity.Grupo.permissoes, no session or session was closed

Mapemaneto na classe Grupo
@ManyToMany(mappedBy=“grupos”)
private List permissoes;

Mapeamento na classe permissão
@ManyToMany
@JoinTable(name=“ADM_GRUPO_PERMISSAO”,
joinColumns=@JoinColumn(name=“PER_ID”),
inverseJoinColumns=@JoinColumn(name=“GRU_ID”))
private List grupos;

mas este ocorre au subir a aplicação ou ao invocar o método getAlgumaCoisa?

outra coisa, coloque seu sódigo entre [CODE]

Preste muita atenção nessa classe LazyInitializationException pq vc vai ve-la bastante, ao menos enquanto vc ñ tiver muita XP com JPA.

O problema aqui é q todo relacionamento x:n é por padrão configurado como LAZY.
Relacionamentos podem ser LAZY ou EAGER. Os relacionamentos EAGER são carragados do banco no momento q a entidade q os possui é carregada. Enquanto os LAZY só são carregados quando vc tenta acessar esse relacionamento, o problema é q p/ fazer isso é necessário q haja uma transação aberta nesse momento, o q nem sempre é o caso.
Relacionamentos LAZY são, quase sempre, uma boa idéia pois eles reduzem a quantidade de memória necessária p/ manter as entidades e o tempo de carregamento delas. Mas infelismente eles só funcionam quando vc está dentro de uma transação. P/ resolver isso use JOIN FETCH nas queries quando vc souber q precisará acessar um relacionamento LAZY de fora da transação em q a entidade foi carregada.

select g from Grupo g join fetch g.permissoes

O JOIN FETCH força um relacionamento b]LAZY[/b] ser carregado como EAGER nessa query.

Ocorreu ao invocar o método no caso foi em tempo de execução
certo?

Oi dev.rafael
Só não entendi se devo criar um método para esse join.
obrigado

vc invocou o método numa jsp, controller, repositório, onde?

Ele é está em um Control do Jsf

Uma solução seria vc mudar o comportamento do relacionamento, como o dev.rafael postou, ManyToMany por padrão tem um comportamento Lazy, se vc mudar para Eager, vai funcionar, porém, toda vez que se carregar um “Grupo”, a query vai fazer um “join” com o “Permissoes”, vc querendo ou não querendo carregar as permissões.

Outra alternativa, seria aplicar o conceito de “openSessionInView” (google -> openSessionInView jsf bean ejb), mas como vc está num contexto EJB, não sei se tem como, pois o bean recebe “uma cópia” (serializada) do Grupo, e nesta “camada” já saiu do Contexto EJB (Alguêm com mais experiência em EJB me corrija se estiver errado, Obrigado).

Sugestão: faça um serviço que recebe o Grupo e retorna suas permissões, vc terá um pouco mais de código, mas vai funcionar, faça funcionar, depois busque uma alternativa, se tiver tempo.

Espero ter ajudado

Obrigado AAAquino essa solução funcionou

Mais me diz uma coisa isso não vai tornar algumas consultas minhas mais lentas?

Por exemplo quando eu quizer listar usuários do sistema ele vai carregar o grupo que ele pertence e suas permissões também?

abraços

Se existe uma associação do tipo


class Usuario

@ManyToOne // <- comportamento default é Eager)
List<Grupo> grupo

sim, irá fazer um join com as 3 tabelas toda vez que se carregar um usuário

Valeu AAAquino e dev.rafael pela força
abraços