카테고리 없음

JPA test - 3

happyst 2024. 10. 31. 16:42
  • camel case를 snake case로 바꾸기 위해 persistence.xml 파일 수정
  • 아래 내용 추가
<property name="hibernate.physical_naming_strategy" value="org.hibernate.boot.model.naming.CamelCaseToUnderscoresNamingStrategy"/>

JPA 연관관계

  • 데이터베이스 테이블에서 FK가 있는 쪽이 연관관계의 주체!
  @ManyToOne  // - fetch type : EAGER
  @JoinColumn(name = "dept_id")
  private Department department;

 

JPA 연관관계 Annotation

Annotation fetch type
OneToOne EAGER
OneToMany EAGER
ManyToOne LAZY
  • fetch type - LAZY : 지연 로딩
  • fetch type - EAGER : 즉시 로딩

단방향 연관관계 (ManyToOne)

Employee.java
package domain;

import javax.persistence.*;

@Entity
@Table(name = "employee")
public class Employee {
  @Id
  @Column(length = 6)
  private String empId;
  @Column(length = 10, nullable = false)
  private String empName;
  //  @OneToOne  // - fetch type : EAGER
  //  @OneToMany  // - fetch type : LAZY
  @ManyToOne  // - fetch type : EAGER
  @JoinColumn(name = "dept_id")
  private Department department;
  private String joinDate;
  private long salary;

  public Employee() {
  }

  public Employee(String empId, String empName, Department department, String joinDate, long salary) {
    this.empId = empId;
    this.empName = empName;
    this.department = department;
    this.joinDate = joinDate;
    this.salary = salary;
  }

  public String getEmpId() {
    return empId;
  }

  public void setEmpId(String empId) {
    this.empId = empId;
  }

  public String getEmpName() {
    return empName;
  }

  public void setEmpName(String empName) {
    this.empName = empName;
  }

  public Department getDepartment() {
    return department;
  }

  public void setDepartment(Department department) {
    this.department = department;
  }

  public String getJoinDate() {
    return joinDate;
  }

  public void setJoinDate(String joinDate) {
    this.joinDate = joinDate;
  }

  public long getSalary() {
    return salary;
  }

  public void setSalary(long salary) {
    this.salary = salary;
  }
}

 

Department.java
package domain;

import javax.persistence.*;

@Entity
@Table(name = "dept")
public class Department {

  @Id
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  private int deptId;

  @Column(name = "dept_name", length = 10, nullable = false)
  private String deptName;

  public int getDeptId() {
    return deptId;
  }

  public void setDeptId(int deptId) {
    this.deptId = deptId;
  }

  public String getDeptName() {
    return deptName;
  }

  public void setDeptName(String deptName) {
    this.deptName = deptName;
  }
}

 

 

Emp_Dept_Test.java
package jpajava;

import domain.Department;
import domain.Employee;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityTransaction;
import javax.persistence.Persistence;

public class Emp_Dept_Test {
  public static void main(String[] args) {
    EntityManagerFactory emf = Persistence.createEntityManagerFactory("jpatest");
    EntityManager em = emf.createEntityManager();
    EntityTransaction tx = em.getTransaction();
    
    tx.begin();
    System.out.println("Transaction START!");
    try {
      Department dept = new Department();
      dept.setDeptName("HR"); // 비영속 상태
      em.persist(dept); // 영속 상태, 즉시 쓰기
      System.out.println("dept 생성");
      
      Employee employee = new Employee();
      employee.setEmpId("202401");
      employee.setEmpName("홍길동");
      employee.setDepartment(dept);
      employee.setSalary(100); // 비영속 상태
      em.persist(employee); // 영속 상태, 지연 쓰기
      System.out.println("employee 생성 #1");

      employee = new Employee();
      employee.setEmpId("202402");
      employee.setEmpName("김연아");
      employee.setDepartment(dept);
      employee.setSalary(200); // 비영속 상태
      em.persist(employee); // 영속 상태, 지연 쓰기
      System.out.println("employee 생성 #2");

      System.out.println("commit 전");
      tx.commit(); // 이 때 employee가 insert됨
      System.out.println("commit 후");
    } catch (Exception e) {
      tx.rollback();
      System.out.println("[Error] : " + e.getMessage());
    } finally {
      System.out.println("Transaction COMPLETED!");
    }
  }
}
실행 결과

 


양방향 연관관계 (ManyToOne, OneToMany)

Department.java
package domain;

import javax.persistence.*;
import java.util.ArrayList;
import java.util.List;

@Entity
@Table(name = "dept")
public class Department {

  @Id
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  private int deptId;

  @Column(length = 10, nullable = false)
  private String deptName;

  @OneToMany(mappedBy = "department")
  List<Employee> employeeList = new ArrayList<>();

  public int getDeptId() {
    return deptId;
  }

  public void setDeptId(int deptId) {
    this.deptId = deptId;
  }

  public String getDeptName() {
    return deptName;
  }

  public void setDeptName(String deptName) {
    this.deptName = deptName;
  }

  public List<Employee> getEmployeeList() {
    return employeeList;
  }

}
  • mappedBy 속성 추가
    • Employee 엔터티의 department 필드를 통해 매핑된다는 의미
    • Employee 엔터티가 연관관계의 주체가 되어 데이터베이스의 FK 관리 권한을 가지게 됨
    • mappedBy 속성이 있는 클래스에서는 Getter만 구현한다. 값을 설정하는건 연관관계의 주체가 할 것이므로 Setter는 구현할 필요가 없음