首页 > 解决方案 > Spring Data JPA DistinctBy 预测

问题描述

冬眠者们美好的一天!我有一个关于DistinctBy子句如何与Spring Data 的投影结合使用的问题

假设我有 3 个课程:

public class Task {
  Long id;
  @ManyToOne(fetch = LAZY)
  @JoinColumn(name = "project_id")
  private Project project;
  @OneToOne
  @JoinColumn(name = "contact_id")
  private Contact assigned;
  Boolean deleted;
  // ...
}

public class Contact {
  Long id;
  // ...
}

public class Project { 
  Long id;
  @OneToMany(fetch = LAZY, mappedBy = "project")
  private Set<Task> tasks;
  // ...
}

这些将是我的域类。请注意,Project 确实对 Tasks 有“One2Many”,而 Contact 没有。现在,我有 2 个用于我的预测的接口和具有 2 种方法的基本 TaskRepo:

public interface JustProject {
  Project getProject();
}

public interface JustAssignee {
  Contact getContact();
}

public class TaskRepo extends CrudRepository<Task, Long>, JpaSpecificationExecutor<Task> {
    List<JustAssignee> findDistinctByDeletedFalse();
    List<JustProject> findDistinctByDeletedFalseAndDeletedFalse();
}

它现在对我有用的方式是,findDistinctByDeletedFalse返回与任务的不同联系人一样多的实例(例如,如果有 10 个任务但只有 3 个联系人,该方法将只返回包含所有 3 个不同联系人的 3 个对象)。相同,findDistinctByDeletedFalseAndDeletedFalse但在项目级别。

现在我在这里有几个问题,很想得到一些帮助来理解它是如何工作的。

非常感谢<3

标签: spring-boothibernatespring-data-jpaspring-dataspring-projections

解决方案


  1. 关键字应用于查询,因此DISTINCT它的效果取决于选择列表,而选择列表又由投影控制。因此,如果您只有project或仅contact在您的投影中,DISTINCT则将仅应用于这些值。但请注意,这在一定程度上依赖于 JPA 规范的边界,如果您看到不同实现的不同行为,我不会感到惊讶。有关针对规范提出的一些相关问题,请参阅https://github.com/eclipse-ee4j/jpa-api/issues/189https://github.com/eclipse-ee4j/jpa-api/issues/124 。

  2. find为了区分仅返回值不同的方法,您可以在方法名称之间和方法名称中添加任何其他字符串By。例如,您可能希望将您的方法重命名findDistinctContactsByDeletedFalsefindDistinctProjectsByDeletedFalse


推荐阅读