jpql查询,返回来自父实体及其嵌套/子实体的自定义dto,其中嵌套实体可为空

m2xkgtsf  于 2021-08-20  发布在  Java
关注(0)|答案(1)|浏览(681)

我目前正在努力使用一个jpql自定义查询,至少乍一看应该是简单的。
堆栈:java 11、spring boot 2.4.5、spring boot starter数据jpa 2.4.8、hibernate core 5.4.16、postgre数据库。
案例
我只需要我的jpql查询在自定义dto中检索3个字段,它们来自父实体及其子/嵌套实体(Map为一对一单向关系),而不是来自域的实体。
域如下所示:

@Entity
@Table(name = "Item")
public class ItemEntity {
  @Id
  private Long id;

  @NotNull
  private String field1;

  @ManyToOne
  @JoinColumn(name = "nestedEntity_id", referencedColumnName = "id")
  private NestedEntity nestedEntity;
  //...
}
@Entity
@Table(name = "Nested")
public class NestedEntity {
  @Id
  private Long id;

  @NotNull
  private String field1;

  @NotNull
  private String field2;
  //...
}
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
public class MyDTO {
  @NotNull
  private String myField;

  private String concatedNestedFields;

  private String otherNestedField;
  //...
}

我认为这很容易,于是做了这样的事情:

@Query("SELECT new my.package.MyDto(itemEntity.field1, CONCAT(itemEntity.nestedEntity.field1, ' ', itemEntity.nestedEntity.field2), itemEntity.nestedEntity.field3) FROM ItemEntity itemEntity WHERE itemEntity.country = :country")
MyDTO findByCountry(@Param("country") CountryEnum country);

特殊性
我不知道它是否相关,但嵌套的实体字段是 @NotNull 注解。
问题
当nestedentity为null时会出现问题:尽管存在“parent”itementity,但查询不返回任何内容。如果nestedentity不为null,则查询有效。
我试过的
我尝试在每个nestedentity字段上使用coalesce()函数,该函数从我们提供的参数返回第一个非null值,如下所示:

@Query("SELECT new my.package.MyDto(itemEntity.field1, COALESCE(CONCAT(itemEntity.nestedEntity.field1, ' ', itemEntity.nestedEntity.field2),'-'), COALESCE(itemEntity.nestedEntity.field3), '-') FROM ItemEntity itemEntity WHERE itemEntity.country = :country")
MyDTO findByCountry(@Param("country") CountryEnum country);

但它也不起作用。
更新我只是尝试了一些方法来消除一些根本原因。如果我运行SpringData/jpa提供的jpa命名查询并返回实体而不是自定义dto,那么即使嵌套实体为null,它也可以工作。它使用嵌套的空实体检索实体。查询如下:

ItemEntity findItemEntityByCountry(@Param("country") CountryEnum country);

我不知道该如何总结,但这可能会帮助那些比我更了解jpa的人(这是很多人。。。xd)。
我没有找到任何关于这个案例的在线资源,我有点迷路了。
如果你们能帮我解决这个令人惊讶的棘手问题,我将不胜感激!
非常感谢你们抽出时间,伙计们!希望这也能帮助其他人:)

tzcvj98z

tzcvj98z1#

尝试下面的左连接

@Query("SELECT new my.package.MyDto(itemEntity.field1,
                        CONCAT(nestedEntity.field1, ' ', nestedEntity.field2),
                        nestedEntity.field3)
        FROM ItemEntity itemEntity left join itemEntity.nestedEntity as nestedEntity
        WHERE itemEntity.country = :country")
MyDTO findByCountry(@Param("country") CountryEnum country);

否则,不要使用concat,只需传递nestedentity.field2并执行连接java端

相关问题