Scott 과 함께 - Domain을 JPA 로 연결

Scott Schema To JPA.

Scott Domain + JPA
 이전 Post는 Oracle DB 의 Scott을 객체로 구현했다. 이번 Post는 JPA와 Scott을 연결한다. 또한 초기 데이터는 Insert 문장이 아닌 JPA로 초기화한다.

Entity 연결

이전 Post 에서 Oracle 의 Scott 예제 객체들로 만들어봤다. 이번에는 JPA로 연결해서 DB에 저장되는 것을 확인한다.

Employee

manager 연결.

 DB에서 상위 결재권자는 사번이 들어가지만, 객체는 다른 Employee 객체다. 관리자-직원이 서로 연결할 수 있도록 연관관계를 지정했다. 다음 Post에서 재귀형 데이터 조회 예제를 만들 계획이다.

@Entity
@Table(name = "emp")
public class Employee {
  ...
  @ManyToOne(fetch = FetchType.LAZY)
  @JoinColumn(name = "mgr")
  private Employee manager;

  @OneToMany(mappedBy = "manager")
  private List<Employee> members = new ArrayList<>();
  ...
}

SalaryGrade/SalaryGrades 연결.

 SalaryGrades를 EMP 테이블에 급여등급 Column이 만들지 않기 위해 @Transient 로 설정한다. Scott 예제의 기존 Table을 최대한 유지하기 위해서다. 

 Employee 의 SalaryGrade는 Salary에 따라 변하기 때문에 호출할 때마다 달라진다. Salary 가 바뀌면 바뀐 급여로 나오도록 설정한다.

@Entity
@Table(name = "emp")
public class Employee {
  ...
  public SalaryGrade getSalaryGrade() {
    return Optional.ofNullable(salaryGrades)
        .map(x -> x.getSalaryGrade(salary))
        .orElse(new SalaryGrade());
  }

  @Override
  public String toString() {
    return "Employee{" +
        "empNo=" + empNo +
        ", name='" + name + '\'' +
        ", job=" + job +
        ", manager=" + Optional.ofNullable(manager).map(Employee::getName).orElse("null") +
        ", hiredate=" + hiredate +
        ", salary=" + salary +
        ", commission=" + commission +
        ", department=" + department.getName() +
        ", salaryGrade=" + getSalaryGrade().getGrade()  +
        '}';
  }
  ...
}

Department

 직원-부서 정보를 한번에 저장을 위해서 영속성 전이(cascade) 옵션을 주었다. 부모 객체를 DB에 저장/수정/삭제할 때, 자식 객체도 자동으로 관리할 수 있다. 

@Entity
@Table(name = "dept")
public class Department {
    ...
    @OneToMany(mappedBy = "department", cascade = CascadeType.PERSIST)
    private List<Employee> employees = new ArrayList<>();
    ...
}

initialize

 데이터 초기화를 위해 만든 method 다. Main에서 실행 후 DB에서 결과를 확인할 예정이다.

public class Scott {
  ...
  public static void main(String[] args) {

    transaction.begin();

    try {
      Scott scott = new Scott();
      scott.initialize(entityManager);
    ...
}

결과

마치며

  다른 부분보다 관리자-직원 연결은 self-reference 라서 어떻게 처리해야 할지 고민이 많았다. 다행이 Java EE JPA예제에서 그 답을 찾을 수 있었다. Java EE Spec도 신경써서 읽어야 겠다. 관련 코드는 Github에 게시했다.

참조


댓글

이 블로그의 인기 게시물

JPA 와 함께 - 느낀점

Scott 과 함께 - Recursive Query 구현하기