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

Relacionamento Bidirecional com Spring JPA

Olá, estou fazendo um relacionamento bidirecional um para muitos e muitos para um. Esse relacionamento está fazendo os insert certo, mas ao realizar a consulta ele gera um sql com left outer join. Gostaria de saber se tem como deixar como join normal? Só trazer os valores se existir nas duas tabelas.

Sql gerado ao realizar a consulta.

select  adesao0_.id as id1_0_, 
        adesao0_.cobranca as cobranca2_0_, 
        adesao0_.comercio as comercio3_0_, 
        adesao0_.departamento as departam4_0_, 
        adesao0_.filial as filial5_0_, 
        adesao0_.frequencia as frequenc6_0_, 
        adesao0_.parcelas as parcelas7_0_, 
        adesao0_.produto as produto8_0_, 
        adesao0_.valor_total as valor_to9_0_         
    from adesao adesao0_ left outer join adesao listamovim1_ 
      on adesao0_.id=listamovim1_.id_adesao left outer join movimento_adesao movimentoa2_ 
      on listamovim1_.adesao_id=movimentoa2_.id left outer join adesao movimentoa2_1_ 
      on movimentoa2_.id=movimentoa2_1_.adesao_id where movimentoa2_.data_prevista<?

Segue abaixo os relacionamentos.

Classe um para muitos.

@Entity
public class Adesao{
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @OneToMany(mappedBy = "adesao", cascade = CascadeType.ALL, orphanRemoval = true)
    private List<MovimentoAdesao> listaMovimentosAdesao = new ArrayList<>();

    /**get e set ***/
}

Classe muitos para um.

@Entity
public class MovimentoAdesao{
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @ManyToOne(fetch = FetchType.EAGER, optional=false)
    @JoinColumn(name = "id_adesao", nullable= false)    
    private Adesao adesao;

    /***get e set **/
}
3 respostas

Oi Renato,

A JPA gera um LEFT JOIN, pois considera que uma Adesao pode ter a lista de MovimentoAdesao vazia.

O seu relacionamento entre MovimentoAdesao e Adesao, que é ManyToOne, está como obrigatorio, mas o contrário não necessariamente será obrigatório.

Nesse caso então você precisa montar uma querie específica.

Algo como:

SELECT a FROM Adesao a INNER JOIN FETCH a.listaMovimentosAdesao

Veja se resolve.

Olá Rodrigo, mas tem como eu marca que Adesao sempre vai ter um MovimentoAdesao? Assim talvez ele gera o sql com inner join

solução!

Acredito que não tem como, se não vai cair em um dead-lock.

Tipo assim, você estaria dizendo que ambos os registros são obrigatórios, mas na hora de inserir uma Adesão, precisaria já ter um MovimentoAdesao inserido no BD, mas quando fosse inserir um MovimentoAdesao, precisaria já ter uma Adesao gravada no BD.

O jeito é utilizar uma querie customizada então.