Pesquisa Many to Many no Hibernate

6 respostas
Basilio

Galera eu tenho o esquema de tabelas abaixo.

Eu preciso fazer uma HQL que dado um Usuario e uma Transacao, me diga se eles tem ligação. Ou seja se o Usuario esta em um Grupo e se esse Grupo tem aquela Transacao. Alguém pode me ajudar?

6 Respostas

jpjcjbr

Bom dia Basilio, tudo bem?

Pelo o que eu entendi do seu modelo:

  • um usuário pertence a um grupo;
  • uma transacao pertence a um grupo;
  • um grupo tem varios usuarios;
  • um grupo tem varias transacoes;

Não existe nada que relacione um usuario com uma transacao, voce só consegue saber se um usuario está em um mesmo grupo que um transacao.

Voce pode consultar os grupos filtrando pelo id da transacao e pelo id do usuario, dai vc descobre se existe combinacao de usuario e transacao num grupo.

Espero ter ajudado.

abs

Basilio

Mas tem como eu fazer essa pesquisa unicamente por HQL? So estou conseguindo fazendo uma busca, colocando a lista que retorna em um for e fazendo outra busca dentro do for. Dessa forma fica muito pesado.

CintiaDR

Dá pra fazer com HQL, com SQL, com produto cartesiano normal, com inner join, fetch join, com exists… vixe.

Coloca os trechos das entidades aqui (só a parte que dá liga uma na outra) que a gente pode ajudar. Porque nem sei se você mapeou as tabelas de relacionamento como entidades ou se vc usou ‘@ManyToMany’.

Mas um jeito tosco de pensar é fazer Grupo leftJoin Grupo_Usuario leftJoin Usuario leftJoin grupoTransacao leftJoin Transacao.

Basilio

Fiz o seguinte método e fiquei satisfeito. Se alguém tiver uma forma melhor…

public static boolean verificaTransacao(Usuario usuario, String transacao) {
        SessionFactory sf = new AnnotationConfiguration().configure("hibernate.cfg.xml").buildSessionFactory();
        Session s = sf.openSession();

        String sql = "SELECT g.nome FROM Grupo g "
                + "WHERE :usuario in (SELECT u.pessoaId FROM g.usuarios u) "
                + "AND :transacao in (SELECT t.arquivo FROM g.transacaos t)";

        Query qr = s.createQuery(sql);
        qr.setParameter("usuario", usuario.getPessoaId());
        qr.setParameter("transacao", transacao);
        if (qr.list().isEmpty()) {
            return false;
        } else {
            return true;
        }
    }
CintiaDR

Basília,

Eu particularmente já tive muitos problemas de velocidade com o ‘in’, então às vezes é mais fácil partir pra um ‘OR’ gigante ou então usar o ‘exists’. Não existe nada mais rápido que ele rs.

E não modificaria muito, veja se funciona.

SELECT g.nome FROM Grupo g 
WHERE exists (SELECT u.pessoaId FROM g.usuarios u where u.pessoaId = :usuario ) 
AND exists (SELECT t.arquivo FROM g.transacaos t where t.arquivo = :transacao )
Basilio

Funcionou sim, quanto a velocidade nao da pra dizer, pq o banco esta com poucas entradas.

Criado 27 de janeiro de 2011
Ultima resposta 27 de jan. de 2011
Respostas 6
Participantes 3