Spring Data JpaRepository "JOIN FETCH" 返回重复项



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

  • 部门
  • 员工

每个员工都在某个部门工作(employee.department_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(使用Set<Department> getAll();2(在@Query注释中使用"SELECT DISTINCT dep"(

FROM Department dep JOIN FETCH dep.employees emp表达式生成本机查询,返回纯结果Department-Employee。每个Department将被返回dep.employees.size()次。这是JPA提供者预期的行为(在您的案例中为Hibernate(。

使用distinct来消除重复似乎是一个不错的选择。CCD_ 11作为查询结果使得不可能得到有序的结果。

您可能希望使用LEFT JOIN FETCHDISTINCT。普通JOIN FETCH使用内部联接,因此查询不会返回没有任何员工的部门。LEFT JOIN FETCH使用外部联接。

我不确定是否在这里使用@Query。如果通过注释@OneToMany@ManyToOne映射这两个实体,则此联接是多余的。第二个时刻,为什么@Basic(fetch = FetchType.LAZY)在这里?也许你应该在@OneToMany中设置惰性初始化?看看这个资源,我希望你会发现它对有用

据我所知,在您提到的用例中,您不需要定义自己的方法,而是使用repository.findAll,它继承自PagingAndSortingRepository,它扩展了CrudRepository,并由SimpleJpaRepository实现。参见此处

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

@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();
}
}

最新更新