代码之家  ›  专栏  ›  技术社区  ›  Al Grant

OneToOne关系和带可选字段的DTO投影(INNER JOIN)

  •  0
  • Al Grant  · 技术社区  · 2 年前

    我有一个实体:

    public class Bird {
    @Id
    @GeneratedValue(strategy = IDENTITY)
    private Long id;
    @OneToOne(optional = true)
    @Fetch(FetchMode.JOIN)
    @JoinColumn(name = "current_transmitter_id", nullable = true)
    private Transmitter currentTransmitter;
    ....
    }
    

    不是每只鸟都有 CurrentTransmitter 相关。

    我的DTO投影查询是:

    @Query("SELECT NEW com.contoso.view.BirdSummaryDTO(b.name, b.sex, b.currentTransmitter ) FROM Bird b")
    List<BirdSummaryDTO> listBirdDTO();
    

    BirdSummaryDTO看起来像:

    public class BirdSummaryDTO {
    
    final String name;
    final String sex;
    final Transmitter currentTransmitter;
    
    public BirdSummaryDTO(Integer id, Transmitter currentTransmitter) {
        this.name = name;
        this.sex = sex;
        this.currentTransmitter = currentTransmitter;
    }
    

    然而,我的查询只返回有发射器的鸟。它正在使用INNER JOIN。

    问: 是否有注释或方法使其返回所有鸟类,无论它们是否有电流发射器?

    0 回复  |  直到 2 年前
        1
  •  0
  •   Al Grant    2 年前

    为了解决这个问题,我不必触摸实体。HQL“隐式联接”,如b.currentTransmitter在HQL中总是内部联接。

    对的更改 DTO -范围从最终到私有:

    public class BirdSummaryDTO {
    
    private String name;
    private String sex;
    private Transmitter currentTransmitter;
    
    public BirdSummaryDTO(Integer id, Transmitter currentTransmitter) {
        this.name = name;
        this.sex = sex;
        this.currentTransmitter = currentTransmitter;
    }
    

    然后在存储库中的查询上更改为LEFT JOIN(即OUTER):

     @Query("SELECT NEW com.contoso.view.BirdSummaryDTO(b.name, b.sex, b.status, b.currentTransmitter) FROM Bird b LEFT JOIN b.currentTransmitter t")
    List<BirdSummaryDTO> listBirdDTO();
    

    笔记 在查询中,我必须显式地声明LEFT JOIN。这会将LEFT JOIN更改为LEFT OUTER JOIN。