我有两个表,一个是customer,另一个是customerDepartment。客户与customerDepartment有一对多的关系。
我有一个特定的搜索条件,我需要搜索部门名称,如果等于,则需要检索所有客户部门行,包括客户。
这就是我试图得到的结果
public interface CustomerRepository extends JpaRepository<Customer,Integer>{
@Query(value="select DISTINCT c from Customer c left join c.custDept cd where cd.deptName like %?1% ")
Page<Customer> findByName(String name, Pageable pageable);
}
@Entity
@Table(name="customer")
public class Customer implements Serializable{
private static final long serialVersionUID = 1L;
@Id
@Column(name= "customer_no",updatable = false, nullable = false)
@GeneratedValue(strategy = GenerationType.SEQUENCE)
private int customerNo;
@Column(name= "customer_name")
private String customerName;
@Column(name= "industry")
private String industry;
@JsonManagedReference
@OneToMany(mappedBy = "customer", cascade = CascadeType.ALL,
fetch=FetchType.LAZY)
private Set<CustomerDepartment> custDept;
}
@Entity
@Table(name = "customer_department")
public class CustomerDepartment implements Serializable{
private static final long serialVersionUID = 1L;
@Id
@Column(name = "dept_id",updatable = false, nullable = false)
@GeneratedValue(strategy = GenerationType.SEQUENCE)
private int depId;
@Column(name = "dept_name")
private String deptName;
@Column(name = "primary_contact")
private String primaryContact;
@JsonBackReference
@ManyToOne(fetch=FetchType.LAZY)
@JoinColumn(name = "customer_no", nullable = false)
private Customer customer;
}
当我搜索DepartmentName = it时,上述JPA查询返回以下结果
{
"content": [
{
"customerNo": 33,
"customerName": "Test1",
"industry": "High-Tech",
"country": "Australia",
"state": "Sa-Jose",
"city": "Sydney",
"custDept": [
{
"depId": 34,
"deptName": "It",
"primaryContact": "Banglore,Kormangala",
},
{
"depId": 35,
"deptName": "sales",
"primaryContact": "Banglore,Kormangala",
}
]
}
]
}
我期望的更像是
{
"content": [
{
"customerNo": 33,
"customerName": "Test1",
"industry": "High-Tech",
"country": "Australia",
"state": "Sa-Jose",
"city": "Sydney",
"custDept": [
{
"depId": 34,
"deptName": "It",
"primaryContact": "Banglore,Kormangala",
}
]
}
]
}
如果这在JPA中是不可能的,有什么办法可以做到这一点。 感谢您的帮助
答案 0 :(得分:0)
是的,我是这样认为的。我评论说:“我认为您的查询是可以的,但是当将结果编组为JSON时,将检索所有关联部门。您应在编组之前查看sql输出并调试并检查查询结果,以了解是否案子。”我继续研究它,我或多或少是正确的。
问题是您没有获取查询的custDept
集合,因此当客户被编组以获取其余响应时,将执行附加查询以获取值,附加查询仅查询所有内容。
2019-05-25 14:29:35.566调试63900 --- [nio-8080-exec-2] org.hibernate.SQL:选择不同的customer0_.customer_no作为customer1_0_,customer0_.customer_name作为customer2_0_,customer0_.industry作为来自客户customer0_的行业3_0_,从左外部加入了customer0_.customer_no = custdept1_.customer_no上的customer_department custdept1_,其中custdept1_.dept_name喜欢吗?限制?
2019-05-25 14:29:35.653调试63900 --- [nio-8080-exec-2] org.hibernate.SQL:选择custdept0_.customer_no作为customer4_1_0_,custdept0_.dept_id作为dept_id1_1_0_0,custdept0_.dept_id作为customer4_1_0_ dept_id1_1_1_1,custdept0_.customer_no作为customer4_1_1_,custdept0_.dept_name作为dept_nam2_1_1_,custdept0_.primary_contact作为primary_3_1_1_来自customer_department custdept0_,其中custdept0_.customer_no =?
如果仅需要查询提供的内容,则需要进行提取,以便custDept
集在被编组之前被初始化。您的查询还存在其他问题。您应该使用sql参数:deptName
并声明它,并且应该提供countQuery
,因为您要返回Page
。
public interface CustomerRepository extends JpaRepository<Customer,Integer>{
@Query(value="select DISTINCT c from Customer c left join fetch c.custDept cd where cd.deptName like %:deptName% ",
countQuery = "select count ( DISTINCT c ) from Customer c left join c.custDept cd where cd.deptName like %:deptName% ")
public Page<Customer> findByName(@Param("deptName") String deptName, Pageable pageable);
为我工作。现在只执行原始查询,结果正确。
{
"content": [
{
"customerNo": 1,
"custDept": [
{
"deptName": "it"
}
]
}
],
最后请注意,根据春季文档,最好将Integer
用于实体中的@Id
。