✔️ 시험 문제에서 발생한 연관관계
이로 인해서
시험문제 <-> 객관식
시험문제 <-> 주관식
객관식 <-> 답안
시험문제 <-> 문제 키워드
4개가 단방향 연관관계를 맺어야 하는 상황이다.
✔️ 연관관계
단방향 연관관계로는 일대다, 다대일이 존재한다.
Exam
<-> ExamProblem
@Entity
@AllArgsConstructor(access = PRIVATE)
@NoArgsConstructor
@Getter
@Builder
public class Exam extends BaseEntity {
@Id
@GeneratedValue(strategy = IDENTITY)
private Long id;
@NotNull
private String subject;
@CreatedDate
private LocalDateTime examTime; // 시험 시작 시간
private LocalDateTime examEndTime; // 시험 응시 종료 시간
@NotNull
private LocalDateTime deadLine; // 시험 과제 마감일
@NotNull
private int memberCount; // 스터디원 수
@NotNull
private int submittedCount; // 문제를 제출한 멤버 수
@NotNull
private int multiChoiceProblemCount; // 팀원들이 객관식 만들어야하는 문제 수 (만들어야하는 문제 수보다 적게 입력된 경우 재 입력?)
@NotNull
private int shortAnswerProblemCount; // 팀원들이 주관식 만들어야하는 문제 수
@NotNull
private int totalMultiChoiceProblemCount; // 시험 객관식 문제 수
@NotNull
private int totalShortAnswerProblemCount; // 시험 주관식 문제 수
// 현재 이와 같은 entity에서 N : 1 관계일 때
// JoinColum
// fetch = LAZY : 기본적으로 지연로딩이 되어서 선언할 필요가 없다.
@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true)
@JoinColumn(name = "exam_id")
private List<ExamProblem> examProblems = new ArrayList<>();
// 객관식 문제
@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true)
@JoinColumn(name = "exam_id")
private List<MultipleChoiceExam> multipleChoiceExams = new ArrayList<>();
// 주관식 문제
@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true)
@JoinColumn(name = "exam_id")
private List<SubjectExam> subjectExams = new ArrayList<>();
// 시험 키워드
@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true)
@JoinColumn(name = "exam_id")
private List<ExamKeyword> examKeywords = new ArrayList<>();
}
@Entity
@AllArgsConstructor(access = PRIVATE)
@NoArgsConstructor
@Getter
public class ExamProblem {
@Id
@GeneratedValue(strategy = IDENTITY)
private Long id;
@NotNull
private String examType; // 문제 유형
@NotNull
private String examTitle; // 스터디 문제 제목
@NotNull
private String examContent; // 스터디 문제 내용
}
Exam에서 @OneToMany
어노테이션을 통해 일대다 연관관계를 맺었다.
@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true)
@JoinColumn(name = "exam_id")
private List<ExamProblem> examProblems = new ArrayList<>();
// 객관식 문제
@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true)
@JoinColumn(name = "exam_id")
private List<MultipleChoiceExam> multipleChoiceExams = new ArrayList<>();
// 주관식 문제
@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true)
@JoinColumn(name = "exam_id")
private List<SubjectExam> subjectExams = new ArrayList<>();
// 시험 키워드
@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true)
@JoinColumn(name = "exam_id")
private List<ExamKeyword> examKeywords = new ArrayList<>();
Exam
<-> ExamProblem
@Entity
@AllArgsConstructor(access = PRIVATE)
@NoArgsConstructor
@Getter
@Builder
public class Exam extends BaseEntity {
@Id
@GeneratedValue(strategy = IDENTITY)
private Long id;
@NotNull
private String subject;
@CreatedDate
private LocalDateTime examTime; // 시험 시작 시간
private LocalDateTime examEndTime; // 시험 응시 종료 시간
@NotNull
private LocalDateTime deadLine; // 시험 과제 마감일
@NotNull
private int memberCount; // 스터디원 수
@NotNull
private int submittedCount; // 문제를 제출한 멤버 수
@NotNull
private int multiChoiceProblemCount; // 팀원들이 객관식 만들어야하는 문제 수 (만들어야하는 문제 수보다 적게 입력된 경우 재 입력?)
@NotNull
private int shortAnswerProblemCount; // 팀원들이 주관식 만들어야하는 문제 수
@NotNull
private int totalMultiChoiceProblemCount; // 시험 객관식 문제 수
@NotNull
private int totalShortAnswerProblemCount; // 시험 주관식 문제 수
}
@Entity
@AllArgsConstructor(access = PRIVATE)
@NoArgsConstructor
@Getter
public class ExamProblem {
@Id
@GeneratedValue(strategy = IDENTITY)
private Long id;
@NotNull
private String examType; // 문제 유형
@NotNull
private String examTitle; // 스터디 문제 제목
@NotNull
private String examContent; // 스터디 문제 내용
@ManyToOne
@JoinColumn(name = "exam_id", nullable = false)
private Exam exam;
}
ExamProblem에서 @ManyToOne
어노테이션을 통해 일대다 연관관계를 맺었다.
@ManyToOne
@JoinColumn(name = "exam_id", nullable = false)
private Exam exam;
💡 참고
참고로, 현재는 ExamProblem 엔티티만 표현했지만 ExamKeyword, SubjectExam, MultipleChoiceExam 엔티티 모두에 Exam엔티티 관련 ManyToOne 어노테이션이 선언되어 있다.
✔️ 장점
✔️ 단점
ExamProblem 테이블 조회 -> 받은 부모 id -> Exam 테이블 조회
)
✔️ 장점
✔️ 단점
OneToMany
관계는 종종 성능 문제를 야기할 수 있다. 특히 Lazy 로딩을 사용하지 않으면, 부모 엔티티를 로드할 때마다 자식 엔티티도 함께 로드될 수 있다.
✏️ 현재 상황에서 데이터 접근을 고려했을 때
💡 참고
현재와 다르게 자식 엔티티의 수가 많은 경우 OneToMany 관계가 성능 저하를 초래할 수 있다.
데이터의 일관성과 트랜잭션 관리의 복잡성도 고려해야 한다.