【发布时间】:2019-09-26 23:37:27
【问题描述】:
以下是我的实体结构。 EmployeeKey 是 Employee 中的 EmbeddedId(复合键)。
这是我想使用 Spring-Data 实现的本机查询。
select DISTINCT(ID), NAME, DEPARTMENT from EMPLOYEE;
我正在尝试使用 基于接口和基于类的 Spring 数据 JPA 预测,但这些方法似乎都不起作用。基于接口的投影给出了我无法取消代理的代理列表。在基于类的投影的构造函数中使用 DISTINCT 是不可能的 AFAIK。
@Entity
@Table(name = "EMPLOYEE")
public class Employee {
@EmbeddedId
private EmployeeKey key;
@Column(name = "NAME")
private String name;
@Column(name = "DEPARTMENT")
private String department;
@Coulmn(name = "AGE")
private Integer age;
//Getter/Setters/Constructors
}
@Embeddable
public class EmployeeKey {
@Column(name = "ID")
String id;
@Column(name = "REGNO")
String regNo;
//Getter/Setters/Constructors
}
@Repository
public interface EmployeRepository extends JpaRepository<Employee, EmployeeKey>{
@Query(value = "select distinct(emp.key.id), emp.name, emp.department from Employee emp")
List<EmployeeInterfaceProjection> findUsingInterfaceProjection();
@Query(value = "select distinct(emp.key.id) as empId, emp.name as empName, emp.department as empDepartment from Employee emp")
List<EmployeeClassProjection1> findUsingClassProjection1();
@Query(value = "select new com.path.to.EmployeeClassProjection2(emp.key, emp.name, emp.department) from Employee emp")
List<EmployeeClassProjection2> findUsingClassProjection2();
@Query(value = "select distinct(emp.key.id) as empId, emp.name as empName, emp.department as empDepartment from Employee emp")
List<Object[]> findUsingObjectProjection();
}
public interface EmployeeInterfaceProjection{
EmployeeKeyInterfaceProjection getKey();
String getName();
String getDepartment();
interface EmployeeKeyInterfaceProjection{
String getId();
}
}
public class EmployeeClassProjection1{
private String empId;
private String empName;
private String empDepartment;
//Getters/Setters, Constructors, Hashcode, Equals
}
public class EmployeeClassProjection2{
private EmployeeKey key;
private String name;
private String department;
//Getters/Setters, Constructors, Hashcode, Equals
}
每种方法都面临的问题
findUsingInterfaceProjection()
这给出了一个我无法取消代理以获取价值的列表。 Hibernate.unproxy/initialize 也无济于事。在代理上进行流式传输并调用 getter 时:getKey()、getName()、getDepartment() 为每个提供 null。
findUsingClassProjection1()
这给出了“没有找到能够从类型 [org.springframework.data.jpa.repository.query.AbstractJpaQuery$TupleConverter$TupleBackedMap] 转换为类型 [com.path.to.EmployeeClassProjection1] 的转换器]“ 错误。
我知道为了解决这个问题,我需要直接在查询中使用参数化构造函数。但是这样做会禁止我在构造函数中使用 DISTINCT。
findUsingClassProjection2()
这种方法实际上是获取数据而不是代理,但我需要不同的过滤。不能在查询的构造函数中使用 DISTINCT。
findUsingObjectProjection()
这很好用,但看起来很粗糙。我希望使用 JPA 预测。
【问题讨论】:
标签: jpa spring-data-jpa spring-data