개요
회사에서 PC방 관련 서비스를 이관하는 작업을 진행 중인데 테이블이 하나 추가되었고, 이 테이블을 기존의 사용하던 real_student(예시) 테이블에서 몇몇 필드가 제거된 테이블이다.(fake_student)
추가된 fake_student와 real_student를 함께 사용할 것이기 때문에 로직 수정이 필요한 상태이다.
요구사항
새로 추가된 fake_student와 real_student를 함께 사용한다는 말을 좀 더 풀어서 설명하자면 fake_student의 PK 값이 있는지 확인하고, 없다면 real_student에서 해당 PK 값을 찾는 것이 핵심 로직이다.
그러나 문제는 기존의 있던 real_student에 많은 테이블들이 조인되어 있다는 점이다. 이를 그대로 두고, fake_student를 이 시스템에 적용해야한다.
해결 방안
처음에는 단순하게 fake_student와 real_student를 강제로 1대1 조인하여 real_student가 조인된 다른 테이블에서 조회 시 자동으로 조인되게 하려고 했다. 그러나 JPA는 어떤 테이블에 대해 CRUD API를 호출하면 해당 테이블 관점에서 조인된 테이블만 호출한다.
@Getter @Setter @ToString
@Entity
@Table(name = "student_support_fund")
public class StudentSupportFund {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "no")
private long no;
@Column(name = "month")
private LocalDate month;
@Column(name = "rank")
private int rank;
@ManyToOne // 조인부분
@JoinColumn(name = "crm",insertable = false, updatable = false,nullable = false)
private realStudent realStudent;
@ManyToOne
@JoinColumn(name = "crm",insertable = false, updatable = false,nullable = false)
private StudentApproved StudentApproved;
}
위 예시를 예로 들자면 다른 테이블의 조인 관계랑은 상관없이 real_student와 student_approved 테이블만 호출한다.
그래서 다른 방법으로 real_student이 조인된 모든 테이블에 fake_student를 추가하는 방법을 생각했다.
많은 로직 수정이 필요하겠지만 두 테이블을 함께 사용할 수 있는 확실한 방법이라 생각한다.
- real_student이 조인되어 있는 테이블에 student_approved 추가(student_support_fund , student_monthly_rank)
- 관련 테이블을 조회하는 부분 로직 수정
- real_student 테이블 조회하는 부분 로직 수정
real_student이 조인되어 있는 테이블에 student_approved 추가하는데 real_student을 조인시킬 때 같은 어노테이션을 사용했는데, 둘 중 하나의 테이블에만 값이 있을 때 오류가 발생했다. null로 반환만 되면 조건문을 통해 두 테이블 중 값이 있는 필드만 사용하면 되는데, 조인이되는순간 해당 FK가 없으면 noEntity 에러가 발생하였다.
핀트를 잘 못 잡아서 지연로딩 문제 인 줄 알고, fetch의 방법을 바꾸고, optional, nullable 등 여러 옵션을 사용했지만 여전히 같은 문제가 발생하였다
.
결과적으로 조인 할 때 FK가 없으면 null로 반환하는 어노테이션 @NotFound(action = NotFoundAction.IGNORE)을 사용하면 아래와 같다.
수정후
@Getter @Setter @ToString
@Entity
@Table(name = "student_support_fund")
public class StudentSupportFund {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "no")
private long no;
@Column(name = "month")
private LocalDate month;
@Column(name = "rank")
private int rank;
@ManyToOne // 조인부분
@NotFound(action = NotFoundAction.IGNORE)
@JoinColumn(name = "crm",insertable = false, updatable = false,nullable = false)
private realStudent realStudent;
@ManyToOne
@NotFound(action = NotFoundAction.IGNORE)
@JoinColumn(name = "crm",insertable = false, updatable = false,nullable = false)
private StudentApproved StudentApproved;
}
/////////////// 사용예시 ///////////////////
StudentSupportFund studentSupportFund = findAllByPk(...)
if(studentSupportFund.getRealStudent() == null)
FakeStudent fakeStudent = studentSupportFund.getFakeStudent();
'개발자로서 살아남기' 카테고리의 다른 글
@RequestBody vs @ModelAttribute 차이점 (0) | 2022.10.12 |
---|---|
Spring boot 환경에서 대용량 엑셀 파일 다운로드 하기 - (1) (0) | 2022.09.29 |
서버개발자로서 살아남기 - 로드 밸런서(Load Balancer) (0) | 2022.03.27 |
서버 개발자로서 살아남기 - hosts 파일 (0) | 2022.02.16 |
서버 개발자로서 살아남기 - 프록시(Proxy)란? (0) | 2022.02.10 |