해결된 질문
작성
·
295
0
@Inheritance(strategy = InheritanceType.JOINED)
public List<Todo> getTodoByPlanIdAndDate_Regular(Plan plan, LocalDate date) {
if (plan.getDtype() == "regular") {
/*regular일 경우 startDate 조건만 걸기*/
return em.createQuery("select o from Todo o where o.plan.dtype = :dtype and o.plan.id =:planId and o.plan.startDate <= :date")
.setParameter("date", date)
.setParameter("planId", plan.getId())
.setParameter("dtype", plan.getDtype())
.getResultList();
}
else {
/*term일 경우 startDate, endDate 조건 둘 다 걸기*/
return em.createQuery("select o from Todo o where o.plan.dtype = :dtype and o.plan.id =:planId and o.plan.startDate <= :date and o.plan.endDate >= :date")
.setParameter("date", date)
.setParameter("planId", plan.getId())
.setParameter("dtype", plan.getDtype())
.getResultList();
}
}
코드로 표현하면 이런 식이 될 것 같습니다.
그런데 문제는 regular일 때 조건은 잘 걸리는데 term일 때 조건이 안 걸린다는 것입니다.
endDate를 resolve할 수 없다고 뜹니다. 저 코드에서는 o.plan.endDate로 조건을 걸었는데 부모인 Plan에는 endDate가 없어서 그런 것 같습니다.
Todo의 연관관계는 부모인 Plan으로 걸려 있기 때문에 자식인 PlanRegular나 PlanTerm으로 조회할 수도 없습니다.
이 문제를 해결하기 위해 Todo도 regular와 term으로 분리하고 모든 Todo 관련 메서드를 regular와 term을 따로 처리하도록 하는...그런 방법을 생각해 봤습니다.
하지만 중복되는 코드가 너무 많아지기도 하고
Plan과 다르게 Todo는 regular와 term이 다르게 가지고 있는 변수가 없어서(Plan의 endDate처럼) 상속을 적용하기는 적합하지 않을 것 같습니다.
이 문제를 해결할 수 있는 방법이 있을까요?
답변 1
0
자문자답입니다. 계속 구글링한 결과 찾았습니다^^... treat를 써서 엔티티를 다운캐스팅하면 되는 거였습니다. 더 좋은 방법이 있을지도 모르겠습니다만...
return em.createQuery("select o from Todo o join o.plan p where p.id =:planId and treat(p as PlanTerm).startDate <= :date and treat(p as PlanTerm).endDate >= :date")
.setParameter("date", date)
.setParameter("planId", plan.getId())
.getResultList();
아직 이 jpa 기본편을 끝까지 듣지 못해서 몰랐는데 이 강의 마지막쯤 객체지향 쿼리 언어 파트에도 나오네요.
역시 김영한님 강의입니다. 프로젝트를 하면서 들을 게 아니라 다 듣고 나서 프로젝트를 했어야 하나 봅니다. 혹시 참고할 사람이 있을지도 몰라서 글은 남겨놓겠습니다.
yeon _leaf님 스스로 잘 해결하셨습니다^^