当前位置: 首页 > 知识库问答 >
问题:

Spring Data JpaRepository“JOIN FETCH”返回重复项

程冥夜
2023-03-14

我正在编写一个简单的Spring Data JPA应用程序。我使用MySQL数据库。有两个简单的表:

  • 部门

每个员工都在某个部门工作(employee.department\u id)。

@Entity
public class Department {
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Id
    private Long id;

    @Basic(fetch = FetchType.LAZY)
    @OneToMany(mappedBy = "department")
    List<Employee> employees;
}

@Entity
public class Employee {
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Id
    private Long id;

    @ManyToOne
    @JoinColumn
    private Department department;
}

@Repository
public interface DepartmentRepository extends JpaRepository<Department, Long> {
    @Query("FROM Department dep JOIN FETCH dep.employees emp WHERE dep = emp.department")
    List<Department> getAll();
}

方法getAll返回一个包含重复部门的列表(每个部门重复的次数与该部门中的员工一样多)。

问题1:我是否正确地认为这是一个与Spring Data JPA无关但与Hibernate有关的功能?
问题2:修复它的最佳方法是什么?(我发现至少有两种方法:1)使用设置


共有3个答案

狄兴业
2023-03-14

您可能希望使用左连接提取以及独立提取。普通的JOIN FETCH使用内部联接,因此您的查询不会返回没有任何员工的部门。LEFT JOIN FETCH使用外部联接。

陶成济
2023-03-14

据我所知,就您提到的用例而言,您不需要定义自己的方法,而是使用存储库。findAll继承自分页和排序存储库,它扩展了CrudRepository,并由SimpleParepository实现。请参见此处

所以只需将存储库界面留空,如下所示,

@Repository
public interface DepartmentRepository extends JpaRepository<Department, Long> {

}

然后在任何需要的地方注入并使用它,例如,让我们使用DepartmentService

public interface DepartmentService {
    
    List<Link> getAll();    
}

@Component
public class DepartmentServiceImpl implements DepartmentService {

    private final DepartmentRepository  repository;    

    // dependency injection via constructor
    @Autowired
    public DepartmentServiceImpl(DepartmentRepository repository) {
        this.repository = repository;
    }

    @Override
    public List<Department> getAll() {  
        return repository.findAll();
    }
}
姬昀
2023-03-14
匿名用户

表达式从Department dep JOIN FETCH dep.employees emp生成本机查询,返回普通结果。将返回每个部门的部门员工。size()次。这是JPA提供程序所期望的行为(在您的情况下是Hibernate)。

使用distinct消除重复项似乎是一个不错的选择<代码>设置

 类似资料:
  • 我购买了一张桌子,DDL为: Purchase表与purchaseproduct有一对多关系,purchaseproduct的DDL为: 以下是我的POJO: 购买:@Entity@Table(name=“Purchase”)@Access(AccessType.Property)公共类购买{private LongProperty IDPurchase;private StringPropert

  • 问题内容: 考虑到此代码,我是否可以 绝对确定 该块始终执行,无论它是什么? 问题答案: 是的,将在执行或代码块后调用。 唯一不会被调用的时间是: 如果您调用 如果您调用 如果JVM首先崩溃 如果JVM在或块中达到了无限循环(或其他不间断,不终止的语句) 操作系统是否强行终止了JVM进程;例如,在UNIX上 如果主机系统死机;例如,电源故障,硬件错误,操作系统崩溃等 如果该块将由守护程序线程执行并

  • 我试图将三列作为一个字符串,但由于某些原因,我只得到NULL。 以下是代码: places表包含name、city和country三列,它不是空的,但在某些列中可以包含NULL。 结果是: 我试着从这篇帖子中得到答案,如果任何字段包含NULL,MySQL CONCAT将返回NULL,但它对我不起作用。

  • 问题内容: 这个问题已经在这里有了答案 : java InetAddress.getLocalHost(); 返回127.0.0.1…如何获得REAL IP? (11个答案) 7年前关闭。 我的问题类似于这个问题。我想获取机器的真实IP(不是127.0.0.1),但是很奇怪,Ubuntu中的以下代码返回了127.0.1.1。 以下是我的完整代码,最初在此处发布在SO中 上面的代码返回127.0.1

  • 问题内容: 每次我运行mysql_fetch_array时,返回带有重复值的数组, 例如 但我只想要数组中的单个结果,我尝试使用 但这没有区别。 问题答案: 这是的预期功能。如果您不希望有“重复项”,而只是具有关联数组,请改用。 例:

  • 原始正则表达式:< code>[v]\d?\.\d 捕获字符串中的“v{N}.{n}”,其中{N}/{n}只是一个数字。我在代码(java)中尝试,但返回false。 代码: 控制台: