[MyBatis/마이바티스] null 과 empty (row가 없거나 row가 null이거나)
(MyBatis returnInstanceForEmptyRow 설정으로 row가 없는 경우와 null 인 경우 구분해주기)
insert 중복 에러가 났다.
update가 수행되어야 하는기능에서 insert를 탄것 같다.
log를 확인해보니,
insert를 하기 전 중복 체크를 위해
select문을 타서 해당 조건에 특정 컬럼 값의 존재하는지 여부를 체크하는 로직에서
null object를 받아 분기문에서 update문이 아닌 insert가 수행되었다.
분명, 해당 select 쿼리를 실행했을 때에는 로우가 존재하는데?
문제는 해당 로우는 존재하나, 특정 컬럼의 값이 존재하지 않을 때이다.
즉,
SELECT query를 * 로 조회했을때에는 하나의 로우가 존재한다.
그리나, 특정 컬럼만 조회하면 그 값이 null 인 상태이기 때문에
리턴받아 인스턴스에 담아 주면 null 인 것 이다.
row = 0을 return받아, 인스턴스가 null 인 경우는 다르다!
경우에 따라 같게 보아 처리하는 프로세스도 존재할 수 도 있으나,
지금같은 경우에는 분명히 다른 경우다.
그럼 어떻게 구분해줄까?
다행히도 작업환경인 MyBatis에서는 이 두개의 값을 구분해주는 설정이 있다.
<settings> <setting name="returnInstanceForEmptyRow" value="true"/> </settings>
위와 같이 configuration.xml 에 추가해주면 되는데,
returnInstanceForEmptyRow 를 설정해 주면된다.
해당 셋팅을 ture로 설정해주면 위와 같은 경우에
로우는 분명 있지만 컬럼 값이 null인 경우에는 empty 인스턴스를 반환해 주어서
if (null(로우가=0) == returnValue)
에서 false 로 갈수 있는 것이다.
즉, 의도한바대로 오늘 겪은 에러문에서 insert말고 update를 수행할 수 있는 것이다.
returnInstanceForEmptyRow 셋팅의 설명은 아래와 같다.
<!-- MyBatis 는 기본적으로 모든 열들의 행이 NULL 이 반환되었을 때 null을 반환한다. 이 설정을 사용하면 MyBatis가 대신 empty 인스턴스를 반환한다. nested results(collection 또는 association) 에도 적용된다. 3.4.2 부터
MyBatis, by default, returns null when all the columns of a returned row are NULL. When this setting is enabled, MyBatis returns an empty instance instead. Note that it is also applied to nested results (i.e. collectioin and association). Since: 3.4.2 -->
셋팅추가로 언어가 가지고 있는 차이를 자동(?)으로 구분해주는 참으로 편한 세상~
출처
http://www.mybatis.org/mybatis-3/ko/index.html