首页 > 解决方案 > 如何使用 JPA 匹配表的列

问题描述

我只是想学习JPA。我有三个实体类看起来像这样。实体类中提到了关系

@Entity
@Table(name="EMPLOYEE")
public class Employee {
    @Id
    @Column(name="EMP_ID")
    private Integer empId;
    @Column(name="EMP_NAME")
    private String empName;
    @Column(name="EMP_ADDR")
    private String address;
    @OnetoOne
    @JoinColumn(name="PROJ_ID")
    private Project project;
    @OnetoOne
    @JoinColumn(name="TASK_ID")
    private Task task;

}

@Entity
@Table(name="PROJECT")
public class Project {
    @Id
    @Column(name="PROJ_ID")
    private Integer projectId;
    @Column(name="PROJ_NAME")
    private String projectName;
    @Column(name="PROJ_STATUS")
    private String projectStatus;

}

@Entity
@Table(name="TASK")
public class Task {
    @Id
    @Column(name="TASK_ID")
    private Integer taskId;
    @Column(name="TASK_NAME")
    private String taskName;
    @Column(name="TASK_STATUS")
    private String taskStatus;

}

我的预期查询是select * from Employee a , Task b where a.proj_id= ? and a.task_id=b.task_id

在我的员工存储库类中,我有一个方法

findEmployeeByProjectProjectId(int projectId).

但我得到了一些多余的数据,不知道如何处理条件a.task_id=b.task_id

不确定我做错了什么。请提出解决方案,或者如果我做错了什么,请纠正我。

标签: hibernatespring-bootjpaspring-data

解决方案


你有 和@OneToOne之间的映射。Employee-ProjectEmployee-Task

的默认Fetch策略@OneToOneEAGER。因此,无论何时您将FETCH Employee实体,关联ProjectTask实体(如果不为空)也将在同一个查询中被提取。您不需要 where 子句 e.task_id=b.task_id。

    /* Repository method */
    /*Function 1*/
    @Query("Select E FROM Employee E WHERE E.project.PROJ_ID = :projID")
    Employee findByProject( @Param("projID") Integer projID);
    /*Function 2*/
    Employee findByProject( Project project); // This method can be used by passing a managed object of project.

   /*Usage of repository call*/
   Employee e = employeeRepo.findByProject(projectId); // Function 1
   Task t = e.getTask(); // this will not cause a query because Task was EAGERLY loaded with Employee entity.
   Project p = e.getProject(); // this will not cause a query because Task was EAGERLY loaded with Employee entity. 

注意:使用 Project 对象的第二个函数不应该像这样使用:

     Project p=new Project();
     p.setPROJ_ID(projID);
     employeeRepo.findByProject(p); // Function 2 This will throw Exception stating that p is transient which cannot be used for querying.

要使用第二种方法,我们可以加载项目代理然后使用它。

    Project p = entityManager.getReference(Project.class, projId);
    employeeRepo.findByProject(p); // Now this is okk

推荐阅读