0

I have a entity:

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;
....
}

Not every bird has a CurrentTransmitter associated.

My DTO projection query is:

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

And the BirdSummaryDTO looks like:

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;
}

However my query only returns birds that have a transmitter. It is using a INNER JOIN.

Q: Is there a annotation or way to make it return all birds, whether they have a current transmitter or not?

Al Grant
  • 2,102
  • 1
  • 26
  • 49

1 Answers1

0

To fix this I did not have to touch the entity. HQL "implicit joins" like b.currentTransmitter in HQL are always inner joins.

Changes to the DTO - scope from final to private:

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;
}

Then on the query in the repository change to a LEFT JOIN (which is 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();

Note On the query I had to explicitly declare the LEFT JOIN. This changes the LEFT JOIN to a LEFT OUTER JOIN.

Al Grant
  • 2,102
  • 1
  • 26
  • 49