【问题标题】:How to search with JpaRepository and nested list of objects?如何使用 JpaRepository 和嵌套的对象列表进行搜索?
【发布时间】:2018-06-08 08:55:39
【问题描述】:

说明

有一个PersonRepositoryPerson 实体, Person 类包含 List<Qualification>Qualification 类有 3 个简单字段。

我尝试在自定义方法上添加 @Query 注释并使用 JPQL 来获取结果,但 Qualification 类字段无法在 JPQL 中进行操作,因为它的存储库本身包含 List<Qualification> 而不仅仅是一个简单的字段Qualification.

如何通过这些 Qualification 的嵌套字段进行搜索?

查询

现在我需要查找资格的 experienceInMonths 大于 3 且小于 9 且资格的名称字段 = 'java' 的人员实体列表。

代码

Person.java

@Data
@Entity
public class Person {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private String id;

@NotEmpty
@Size(min = 2)
private String name;

@NotEmpty
@Size(min = 2)
private String surname;

@ElementCollection(targetClass = java.util.ArrayList.class, fetch = FetchType.EAGER)
private List<Qualification> qualifications = new ArrayList<>();

}

PersonRepository.java

@Repository
public interface PersonRepository extends JpaRepository<Person, String> {
}

Qualification.java

@Data
@AllArgsConstructor
public class Qualification implements Serializable {

    @Id @GeneratedValue
    private String id;
    private String name;
    private String experienceInMonths;
}

编辑:不重复this post,因为这里是嵌套对象的集合。不仅仅是单一参考。

【问题讨论】:

标签: java jpa spring-boot spring-data


【解决方案1】:

首先,将experienceInMonthsString更改为int(否则无法将字符串与数字进行比较)。然后你可以尝试使用这个“香肠”:

List<Person> findByQualifications_experienceInMonthsGreaterThanAndQualifications_experienceInMonthsLessThanAndName(int experienceGreater, int experienceLess, String name);

或者你可以尝试使用这个相当不错的方法:

@Query("select p from Person p left join p.qualifications q where q.experienceInMonths > ?1 and q.experienceInMonths < ?2 and q.name = ?3")
List<Person> findByQualification(int experienceGreater, int experienceLess, String name);

【讨论】:

  • 它在本地对您有用吗? JPQL 版本给了我org.hibernate.QueryException: cannot dereference scalar collection element: 和香肠之一:Caused by: java.lang.IllegalStateException: Illegal attempt to dereference path source [null] of basic type。即使将 Qualification#experienceInMonths 类型更改为 int
  • @DevDio 尝试将@Entity 添加到Qualification 并将@ElementCollection 替换为@OneToMany(类似的变体对我有用...)
  • 好的,终于让它工作了,但它需要在 Hibernate 中实现单独的Qualification 表。它将 FK 持有人(@Entity,具有@ManyToOne 的附加字段人)+QualificationRepository 是强制性的。还测试了提议的方法,带有 JPQL 的版本运行良好,但需要将“香肠”名称调整为:findByQualifications_experienceInMonthsGreaterThanAndQualifications_experienceInMonthsLessThanAndQualifications_Name。否则它会搜索人名。非常感谢@Cepr0 的帮助!
  • @DevDio 'QualificationRepository 是强制性的' - 如果您使用 @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true),则没有必要。然后,您可以只使用一个 Person 存储库来存储这两个实体。
【解决方案2】:

W 可以在方法名称中使用“_”(下划线)字符来定义 JPA 应该尝试拆分的位置。

在这种情况下,我们的方法名称将是

List<Person> findByQualification_name(String name);

【讨论】:

猜你喜欢
  • 2019-02-16
  • 1970-01-01
  • 1970-01-01
  • 2011-12-29
  • 1970-01-01
  • 2012-04-12
  • 2021-06-11
  • 1970-01-01
  • 2020-06-08
相关资源
最近更新 更多