๐ ๋ฌธ์ ์ํฉ
QueryDSL๋ก ์ํฐํฐ ๊ฐ์๋ฅผ ์กฐํํ ๋ ๋ค์๊ณผ ๊ฐ์ ์ฝ๋ ์ฌ์ฉํ๋ค.
return queryFactory
.select(sender.count())
.from(sender)
.where(sender.courier.eq(courier), sender.isDeleted.isFalse())
.fetchOne(); // โ ๏ธ ๊ฒฝ๊ณ ๋ฐ์!
์ด ์ฝ๋์์ IDE ๋๋ ์ปดํ์ผ๋ฌ๊ฐ ๋ค์๊ณผ ๊ฐ์ ๊ฒฝ๊ณ ๊ฐ ๋์์ก๋ค.
โ Unboxing of 'fetchOne()' may produce 'NullPointerException'
๐ ์ ์ด๋ฐ ๊ฒฝ๊ณ ๊ฐ ๋ฐ์ํ ๊น?
- fetchOne()์ nullableํ Long ๊ฐ์ฒด๋ฅผ ๋ฐํํ๋ค.
- ํ์ง๋ง ๋ฐํ ํ์ ์ long(๊ธฐ๋ณธํ)์ผ๋ก ์ ์ธํด๋ฒ๋ฆฌ๋ฉด → ์ธ๋ฐ์ฑ ๊ณผ์ ์์ null์ด๋ฉด NPE ๋ฐ์!
์ฆ, ์ด ์ฝ๋๋ ์คํ ์ค NPE๊ฐ ๋ฐ์ํ ์ ์๋ ์ํ์ด ์๋ค๋ ์๋ฏธ๋ค.
๐ ํด๊ฒฐ ๋ฐฉ๋ฒ
๋ฐฉ๋ฒ 1. Optional์ ํ์ฉํด ์์ ํ๊ฒ ์ธ๋ฐ์ฑ
Long count = queryFactory
.select(sender.count())
.from(sender)
.where(sender.courier.eq(courier), sender.isDeleted.isFalse())
.fetchOne();
return Optional.ofNullable(count).orElse(0L);
๋ฐฉ๋ฒ 2. ์ผํญ ์ฐ์ฐ์ ์ฌ์ฉ
Long count = queryFactory
.select(sender.count())
.from(sender)
.where(sender.courier.eq(courier), sender.isDeleted.isFalse())
.fetchOne();
return count != null ? count : 0L;
๋ฐฉ๋ฒ 3. ํ ์ค๋ก ์ฒ๋ฆฌ (๊ฐ๋ ์ฑ์ด ๋จ์ด์ง ์ ์์)
return Optional.ofNullable(
queryFactory
.select(sender.count())
.from(sender)
.where(sender.courier.eq(courier), sender.isDeleted.isFalse())
.fetchOne()
).orElse(0L);
๐ก ์ธ์ null์ด ๋ฐํ๋ ์ ์์๊น?
- .count()๋ ๋ณดํต 0์ ๋ฐํํ ๊ฒ ๊ฐ์ง๋ง,
- QueryDSL์ .fetchOne()์ ์กฐ๊ฑด์ด ์์ ํ ๋ฐฐ์ ๋๋ฉด null์ด ๋ ์ ์์
- ๋ฐ๋ผ์ ์์ ํ๊ฒ null ์ฒดํฌ๋ฅผ ํด์ฃผ๋ ๊ฒ์ด ์ข๋ค.