JPQL 查询,用于返回自定义 DTO,来自父实体及其嵌套/子实体,具有可为空的嵌套实体



我目前正在构建一个JPQL自定义查询,至少乍一看应该很简单。

堆栈:Java 11,spring-boot 2.4.5,spring-boot starter数据jpa 2.4.8,hibernate内核5.4.16,Postgre数据库。

案例

我只需要我的JPQL查询在自定义DTO中检索3个字段,这些字段来自父实体及其子实体/嵌套实体(映射为一对一单向关系(,而不是域中的实体

域如下:

@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,则查询有效。

我尝试了什么

我尝试使用COALESCE((函数,它在每个nestedEntity字段上返回我们给出的参数中的第一个非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-Named查询,并返回实体而不是我的自定义DTO,即使嵌套实体为null,它也能工作。它确实检索了带有嵌套null实体的实体。查询如下:

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

我不知道该怎么总结,但它可能会帮助那些比我更了解JPA的人(这是很多人…XD(。

我没有找到任何关于这个案子的在线资源,我有点不知所措。

如果你们能帮我解决这个小问题,我将不胜感激

非常感谢你们抽出时间!希望这也能帮助其他人:(

尝试以下左加入

@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端进行连接

相关内容

  • 没有找到相关文章

最新更新