我目前正在努力使用一个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)。
我没有找到任何关于这个案例的在线资源,我有点迷路了。
如果你们能帮我解决这个令人惊讶的棘手问题,我将不胜感激!
非常感谢你们抽出时间,伙计们!希望这也能帮助其他人:)
1条答案
按热度按时间tzcvj98z1#
尝试下面的左连接
否则,不要使用concat,只需传递nestedentity.field2并执行连接java端