title: Spring/JPA/Hibernate How to Perform Join of Two Entities In One Repository
body: <p>First let's say we have two tables. One table is an <strong>Employee</strong> table with the following columns:</p>
  
  <pre>
  EMPLOYEE:
  ------------------------
  emp_id (int, primary key)
  emp_name (varchar(125))
  emp_dept (foreign key)
  emp_intro (text)
  </pre>
  
  <p>The other table is a <strong>Department</strong> table with the following columns:</p>
  
  <pre>
  DEPARTMENT:
  -----------
  dept_id (int, primary key)
  dept_label (varchar(25))
  </pre>
  
  <p>Here is a sample of the table's values</p>
  
  <pre>
  DEPARTMENT:
  ------------------------
  dept_id    | dept_label
  ------------------------
   1         | Sales
  ------------------------
   2         | Technology
  ------------------------
   3         | Finance
  </pre>
  
  <p>In order to return the employee's info with a status label, we need to either perform a JOIN:</p>
  
  <pre><code>SELECT e, d.dept_label FROM employees JOIN department d ON d.dept_id = e.emp_dept
  </code></pre>
  
  <p>or a multi-table select:</p>
  
  <pre><code>SELECT e.emp_id, e.emp_name, d.dept_label, e.emp_intro FROM employees e, department d WHERE e.emp_dept = d.dept_id
  </code></pre>
  
  <p>However, when using JPA/Hibernate, we need to create two classes:</p>
  
  <p><strong>Employee.java</strong></p>
  
  <pre><code>package com.example.entities;
  
  import java.io.Serializable;
  
  import javax.persistence.Column;
  import javax.persistence.Entity;
  import javax.persistence.GeneratedValue;
  import javax.persistence.GenerationType;
  import javax.persistence.Id;
  import javax.persistence.Table;
  
  @Entity
  @Table(name = "employees")
  public class Employee implements Serializable {
      private static final long serialVersionUID = 1L;
  
      @Id
      @GeneratedValue(strategy = GenerationType.IDENTITY)
      @Column(name = "emp_id")
      private long emp_id;
  
      @Column(name = "emp_name")
      private String emp_name;
  
      @Column(name = "emp_dept")
      private Integer emp_dept;
  
      @Column(name = "emp_intro")
      private String emp_intro;
  
      public long getEmp_id() {
          return emp_id;
      }
  
      public void setEmp_id(long emp_id) {
          this.emp_id = emp_id;
      }
  
      public String getEmp_name() {
          return emp_name;
      }
  
      public void setEmp_name(String emp_name) {
          this.emp_name = emp_name;
      }
  
      public Integer getEmp_dept() {
          return emp_dept;
      }
  
      public void setEmp_dept(Integer emp_dept) {
          this.emp_dept = emp_dept;
      }
  
      public String getEmp_intro() {
          return emp_intro;
      }
  
      public void setEmp_intro(String emp_intro) {
          this.emp_intro = emp_intro;
      }
  
      public static long getSerialversionuid() {
          return serialVersionUID;
      }
  
  }
  </code></pre>
  
  <p><strong>Department.java</strong></p>
  
  <pre><code>package com.example.entities;
  
  import java.io.Serializable;
  
  import javax.persistence.Column;
  import javax.persistence.Entity;
  import javax.persistence.GeneratedValue;
  import javax.persistence.GenerationType;
  import javax.persistence.Id;
  import javax.persistence.Table;
  
  @Entity
  @Table(name = "departments")
  public class Department implements Serializable {
      private static final long serialVersionUID = 1L;
  
      @Id
      @GeneratedValue(strategy = GenerationType.IDENTITY)
      @Column(name = "dept_id")
      private long dept_id;
  
      @Column(name = "dept_label")
      private String dept_label;
  
      public long getDept_id() {
          return dept_id;
      }
  
      public void setDept_id(long dept_id) {
          this.dept_id = dept_id;
      }
  
      public String getDept_label() {
          return dept_label;
      }
  
      public void setDept_label(String dept_label) {
          this.dept_label = dept_label;
      }
  
      public static long getSerialversionuid() {
          return serialVersionUID;
      }
  
  }
  </code></pre>
  
  <p>Then, there is the repository (DAO):</p>
  
  <p><strong>EmployeeRepository</strong></p>
  
  <pre><code>package com.example.repository;
  
  import.java.util.List;
  
  import org.springframework.data.jpa.repository.JpaRepository;
  import org.springframework.data.jpa.repository.Query;
  
  import com.example.entities.Employee;
  
  public interface EmployeeRepository extends JpaRepository&lt;Employee, Long&gt; {
  
      @Query("select e, d.dept_label FROM Employee e JOIN Department d ON "
      + "d.dept_id = e.emp_id")
      public List&lt;Employee&gt; return getEmployees();
  
  }
  </code></pre>
  
  <p>and lastly, the Java controller that binds the classed query to an endpoint of the application:</p>
  
  <p><strong>EmployeeController.java</strong></p>
  
  <pre><code>package com.example.controllers;
  
  import java.util.List;
  
  import org.springframework.beans.factory.annotation.Autowired;
  import org.springframework.stereotype.Controller;
  import org.springframework.web.bind.annotation.RequestBody;
  import org.springframework.web.bind.annotation.RequestMapping;
  import org.springframework.web.bind.annotation.ResponseBody;
  
  import com.example.entities.Department;
  import com.example.entities.Employee;
  import com.example.repository.EmployeeRepository;
  
  @Controller
  public class EmployeeController {
  
      @Autowired
      EmployeeRepository er;
  
      @RequestMapping(value = "/getEmployees")
      public @ResponseBody List&lt;Employee&gt; getEmployees() {
          return er.getEmployees();
      }
  
  }
  </code></pre>
  
  <p>I have already tested this entire structure with only retrieving rows inside of the Employee table (i.e. @Query("SELECT e FROM Employee e") ) and everything returns as is.</p>
  
  <p><strong>MY MAIN ISSUE</strong> is how does one return a JOIN QUERY while the query is inside of a specific class (table), being Employee, if I require contents inside of Department?</p>
  
  <p>I've already tried @JoinColumn annotations and that didn't work as well (perhaps I did it wrong).</p>
  
  <p>Any ideas? Thanks.</p>