코딩항해기
[Error/Spring] EmptyResultDataAccessException 본문
기능 테스트를 하는데 EmptyResultDataAccessException 예외가 발생했다.
해당 예외는 조회한 결과 데이터가 없다는 예외로, 분명 데이터가 존재하는데 조회가 되지 않는다.
전달하는 데이터 오류
해당 쿼리까지 제대로 찾아간 것이 로그로 보이니 condition값의 문제는 아니다.
로그를 볼 때 쿼리를 실행하는데 필요한 storeNum의 값이 1로 View에서 Controller, Model로 잘 전달되고 있으므로 전달하는 데이터의 문제는 아니다.
사실 필요한 데이터가 전달되지 않았다면 쿼리문이 정상 실행되지 않아 다른 예외가 발생했을 것이기 때문에 데이터 전달 문제는 아니다. (1을 전달해야하는데 99를 전달한 상황이 아닌 이상)
쿼리문 조건 문제
쿼리문이 정상 실행되었으니 문법 문제는 아니지만 쿼리문 구조 상 어떠한 데이터도 나올 수 없는 경우가 있다. (항상 false를 반환하는 조건이 있다던지, join 조건이 잘못되었다던지 등등)
해당 하는 쿼리문을 찾아서 실행했다.
항상 false를 반환할만한 조건은 없었으며, 데이터가 있지만 조회되지 않고 있어 view만 따로 조회해봤다.
View 확인
어떠한 조건이 없는 상태임에도 결과값이 나오지 않는 경우 view 조건이 잘못되어 있을 수 있다.
해당 view create 쿼리문을 살펴본다.
create or replace
algorithm = UNDEFINED view `fishshapedbread`.`bb_view_store_join` as
select
`s`.`STORE_NUM` as `STORE_NUM`,
`s`.`STORE_NAME` as `STORE_NAME`,
`s`.`STORE_ADDRESS` as `STORE_ADDRESS`,
`s`.`STORE_ADDRESS_DETAIL` as `STORE_ADDRESS_DETAIL`,
`s`.`STORE_CONTACT` as `STORE_CONTACT`,
`s`.`STORE_CLOSED` as `STORE_CLOSED`,
`s`.`STORE_SECRET` as `STORE_SECRET`,
`sm`.`STORE_MENU_NORMAL` as `STORE_MENU_NORMAL`,
`sm`.`STORE_MENU_VEG` as `STORE_MENU_VEG`,
`sm`.`STORE_MENU_MINI` as `STORE_MENU_MINI`,
`sm`.`STORE_MENU_POTATO` as `STORE_MENU_POTATO`,
`sm`.`STORE_MENU_ICE` as `STORE_MENU_ICE`,
`sm`.`STORE_MENU_CHEESE` as `STORE_MENU_CHEESE`,
`sm`.`STORE_MENU_PASTRY` as `STORE_MENU_PASTRY`,
`sm`.`STORE_MENU_OTHER` as `STORE_MENU_OTHER`,
`sp`.`STORE_PAYMENT_CASHMONEY` as `STORE_PAYMENT_CASHMONEY`,
`sp`.`STORE_PAYMENT_CARD` as `STORE_PAYMENT_CARD`,
`sp`.`STORE_PAYMENT_ACCOUNT` as `STORE_PAYMENT_ACCOUNT`,
`sw`.`STORE_WORK_WEEK` as `STORE_WORK_WEEK`,
`sw`.`STORE_WORK_OPEN` as `STORE_WORK_OPEN`,
`sw`.`STORE_WORK_CLOSE` as `STORE_WORK_CLOSE`,
(case
when ((
select
count(0)
from
`fishshapedbread`.`bb_declare`
where
(`fishshapedbread`.`bb_declare`.`STORE_NUM` = `s`.`STORE_NUM`)) > 0) then 'Y'
else 'N'
end) as `STORE_DECLARED`
from
((((`fishshapedbread`.`bb_store` `s`
join `fishshapedbread`.`bb_store_menu` `sm` on
((`s`.`STORE_NUM` = `sm`.`STORE_NUM`)))
join `fishshapedbread`.`bb_store_payment` `sp` on
((`s`.`STORE_NUM` = `sp`.`STORE_NUM`)))
join `fishshapedbread`.`bb_store_work` `sw` on
((`s`.`STORE_NUM` = `sw`.`STORE_NUM`)))
join `fishshapedbread`.`bb_declare` `d` on
((`s`.`STORE_NUM` = `d`.`STORE_NUM`)));
현재 생략가능한 부분들이 너무 많이 적혀있어서 필요없는 부분만 정리해 알아보기 쉽도록 변경했다.
-- *create or replace : 만약 view가 없다면 생성, 이미 있다면 해당 조건으로 변경해 생성 (delete + create 효과를 준다)
CREATE OR REPLACE VIEW bb_view_store_join AS
SELECT
s.STORE_NUM,
s.STORE_NAME,
s.STORE_ADDRESS,
s.STORE_ADDRESS_DETAIL,
s.STORE_CONTACT,
s.STORE_CLOSED,
s.STORE_SECRET,
sm.STORE_MENU_NORMAL,
sm.STORE_MENU_VEG,
sm.STORE_MENU_MINI,
sm.STORE_MENU_POTATO,
sm.STORE_MENU_ICE,
sm.STORE_MENU_CHEESE,
sm.STORE_MENU_PASTRY,
sm.STORE_MENU_OTHER,
sp.STORE_PAYMENT_CASHMONEY,
sp.STORE_PAYMENT_CARD,
sp.STORE_PAYMENT_ACCOUNT,
sw.STORE_WORK_WEEK,
sw.STORE_WORK_OPEN,
sw.STORE_WORK_CLOSE,
-- 신고가 하나라도 있다면 Y, 아니라면 N을 표기하는 계산필드
CASE
WHEN EXISTS (
SELECT 1
FROM bb_declare
WHERE bb_declare.STORE_NUM = s.STORE_NUM
) THEN 'Y'
ELSE 'N'
END AS STORE_DECLARED
FROM bb_store s
JOIN bb_store_menu sm ON s.STORE_NUM = sm.STORE_NUM
JOIN bb_store_payment sp ON s.STORE_NUM = sp.STORE_NUM
JOIN bb_store_work sw ON s.STORE_NUM = sw.STORE_NUM;
이렇게 다시 View를 살펴보면 join 조건에 문제가 있음을 알 수 있다. 가게와 신고는 항상 서로 데이터가 존재해야하는 1대 다 관계가 아니라 신고가 없을 수 있는 선택적 일대다 관계이므로 join이 아닌 left join과 같은 조건을 사용해야한다.
원인
현재 view의 join 조건으로 인해 신고가 없으면 가게가 조회되지 않는 상황인 것이다. 그래서 신고가 없기 때문에 해당 가게 정보가 조회 되지 않아 EmptyResultDataAccessException 예외가 발생했다.
설계를 이렇게 한 적이 없는데,, 신고 개수나 조건관련 부분도 설계와 전혀 일치하지 않아서 Model파트에서 설계 이해 과정 중 오류가 있었거나 휴먼 에러로 보인다. 일단 현재 발생한 에러는 join 조건을 left join으로 수정해 해결할 수 있다.
수정 후 조회해보면 데이터가 정상 출력된다.
'Error solution' 카테고리의 다른 글
[Error/Spring] UncategorizedSQLException (1) | 2024.10.29 |
---|---|
[Error/Spring] Mapper : SQLErrorCodeSQLExceptionTranslator (0) | 2024.10.27 |
[Error/Spring] SQLErrorCodeSQLExceptionTranslator (0) | 2024.10.26 |
[Error/Lombok] eclipse에서 Lombok 정상구동 하지 않을 때 (2) | 2024.10.22 |
[Error/Spring] NoClassDefFoundError : org/.../JdkVersion (0) | 2024.10.22 |