티스토리 뷰

Language/JAVA

JPA 1:N M:1 OneToMany ManyToOne 매핑

KyeongRok Kim 2023. 1. 19. 05:01

개요

아래 요구사항에 맞게 1:N M:1로 구성한 CourseUser 오브젝트입니다.

JPA에서 @ManyToMany가 있지만 실제 상황에서는 쓰기 어렵기 때문에 1:N M:1로 구현 합니다.

테이블은 Course, User, CourseUser 총 3개가 만들어집니다.

 

요구사항

코스(Course)에는 학생이 들어갑니다.

한명의 학생은 여러개의 코스를 수강할 수 있습니다.

한개의 코스에는 여러명의 수강생이 Assign될 수 있습니다.

 

Course

CourseUserEntity와 관계를 맺습니다.

@Entity
public class CourseEntity extends BaseEntity{
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    //기수 이름
    private String name;

    //설명
    private String description;

    @Enumerated(EnumType.STRING)
    private CourseStatus courseStatus;

    //시작일
    @DateTimeFormat(pattern = "yyyy-MM-dd")
    private Date startDate;

    //종료일
    @DateTimeFormat(pattern = "yyyy-MM-dd")
    private Date endDate;

    @OneToMany(mappedBy = "courseEntity")
    private List<TaskEntity> taskEntities;

    //기수 만든 사람
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "user_id")
    private User user;

    @OneToMany(mappedBy = "courseEntity")
    private List<CourseUserEntity> courseUserEntity;

}

 

User

User도 역시 CourseUserEntity와 관계를 맺습니다.

@Entity
public class User extends BaseEntity{

    @Id @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String userName;
    private String realName;
    private String password;

    @Enumerated(EnumType.STRING)
    private Role role;

    @OneToMany(mappedBy = "user")
    private List<TaskEntity> tasks;

    @OneToMany(mappedBy = "user", cascade = CascadeType.ALL)
    private List<CourseUserEntity> courseUserEntity;

    public void setRole(Role role) {
        this.role = role;
    }
}

 

"cascade" 속성은 JPA(Java Persistence API)에서 엔티티 간의 연관 관계를 처리할 때 사용됩니다. 이 속성은 부모 엔티티의 상태 변화가 자식 엔티티에 영향을 줄 때 어떻게 처리할지를 정의합니다. "cascade"의 값은 연관된 엔티티에 대한 작업을 지정하는 데 사용됩니다.

여기서 "cascade = CascadeType.ALL"은 부모 엔티티의 모든 상태 변화가 자식 엔티티에 영향을 주는 것을 의미합니다. 즉, 부모 엔티티가 영속화, 수정, 삭제되면 자식 엔티티도 같은 작업이 자동으로 적용됩니다.

여러 가지 "CascadeType" 값이 있습니다. 몇 가지 일반적인 옵션은 다음과 같습니다:

  1. ALL: 모든 상태 변화를 자식 엔티티에 적용합니다.
  2. PERSIST: 영속화 작업이 수행될 때 자식 엔티티에도 영속화 작업을 수행합니다.
  3. MERGE: 병합 작업이 수행될 때 자식 엔티티에도 병합 작업을 수행합니다.
  4. REMOVE: 삭제 작업이 수행될 때 자식 엔티티도 삭제됩니다.
  5. REFRESH: 부모 엔티티가 리프레시될 때 자식 엔티티도 리프레시됩니다.
  6. DETACH: 부모 엔티티가 분리(detach)될 때 자식 엔티티도 분리됩니다.

이렇게 함으로써, "cascade" 속성을 사용하여 부모-자식 엔티티 간의 동작을 보다 효율적으로 관리할 수 있습니다.

 

CourseUser

이 부분이 가장 중요 합니다. @ManyToOne이 2개가 들어있습니다.

CourseUser입장에서는 1:M N:1 에서 M, N을 담당하고 있기 때문에 자신은 Many가 됩니다.

@Entity
@Getter
@Setter
public class CourseUser {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @ManyToOne
    @JoinColumn(name = "user_id")
    private User user;

    @ManyToOne
    @JoinColumn(name = "course_entity_id")
    private CourseEntity courseEntity;
}

 

 

Fetch Lazy, Eager

기본값은 Lazy 입니다.

  1. Fetch Eager (즉시 로딩):
    • 즉시 로딩은 주 객체가 데이터베이스에서 검색될 때 관련된 데이터가 즉시 로드됩니다.
    • 예상되는 나중에 필요할 것으로 예상되는 관련된 엔터티나 컬렉션을 미리 로드합니다.
    • 즉시 로딩은 관련된 데이터가 크거나 항상 필요하지 않은 경우에는 성능 문제를 일으킬 수 있으므로 주의가 필요합니다.
  2. Fetch Lazy (지연 로딩):
    • 지연 로딩은 주 객체와 관련된 데이터가 함께 로드되지 않습니다. 대신, 관련 데이터가 명시적으로 액세스되거나 요청될 때만 로드됩니다.
    • 지연 로딩은 검색 시 필요한 데이터만로드하여 성능을 최적화하는 데 사용됩니다.
    • 초기 오버헤드를 줄이는데 도움이 되지만, 관련 데이터가 나중에 액세스될 때 추가적인 데이터베이스 쿼리가 필요할 수 있습니다.
728x90
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/12   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31
글 보관함