Mysql
 sql >> Base de Dados >  >> RDS >> Mysql

problemas com OneToMany incluindo uma cláusula de filtro no spring jpa


  • Significado de select d from TKBData d JOIN d.columns c WHERE c.name = column1 é
    1. Encontre um objeto TKBData onde ele tenha uma column associada objeto para o qual name é column1
    2. Depois de decidir qual TKBData tem pelo menos uma column objeto para o qual name é column1 , então ele retornará todas as suas column associadas objetos sobre o qual você não tem controle no JPA. (consulte Minha resposta para outra pergunta ). Alternativa é escrever sql nativo e retornar objetos não-entidade personalizados
    3. Por exemplo, você tem TKBDATA_1 com column1 e column2 associado, você também tem TKBDATA_2 com column3 associado.
    4. Quando você executa sua consulta, ela ignora TKBDATA_2 e decide retornar TKBDATA_1 pois tem pelo menos uma column objeto com name =column2 . Mas depois disso você não tem controle sobre qual column associada objetos a serem retornados para TKBDATA_1 e o JPA retornará todos os objetos de coluna associados
    5. Se você não tiver certeza do motivo, leia sobre a sessão de hibernação. Como ela fornece uma apresentação exclusiva de qualquer entrada associada na memória. É a base para sua dirty checking e repeatable read

  • Atualize seu @OneToMany do seguinte modo
   @OneToMany(fetch = FetchType.EAGER, 
           cascade = CascadeType.ALL, orphanRemoval = true)
   @Builder.Default
   @JoinTable(name = "TKBDATA_TKBCOLUMN", 
           joinColumns = @JoinColumn(name = "TKBDATA_ID"), 
           inverseJoinColumns = @JoinColumn(name = "COLUMNS_ID"))
   private Set<TKBColumn> columns = Sets.newHashSet();

  • Quando se trata de linguagem de consulta JPA, gostaria de pensar em termos de consulta a uma coleção de objetos na memória.

  • Então agora tente descrever o significado das duas consultas a seguir em termos de objetos.
   select d from TKBData d LEFT JOIN d.columns c WHERE c.name = :name
           vs
   select d from TKBData d JOIN d.columns c WHERE c.name = :name

  • Não se esqueça, ao contrário do sql, onde você está selecionando quaisquer colunas aqui que você disse que deseja selecionar objetos TKBData e restringindo quais objetos TKBData retornar.

  • Portanto, para obter o mesmo resultado do seu sql nativo, use a segunda consulta JPA

Observação:

Mesmo que você tenha usado uma junção esquerda em sua consulta sql, é efetivamente uma consulta sql de junção interna porque você também aplicou um where condição para a tabela mais à direita nessa junção.