default method๋ก JpaRepository ์ข ๋ ์ฐ์ํ๊ฒ ์จ๋ณด๊ธฐ
๊ฐ์
Spring Data JPA์์ JpaRepository ์ธํฐํ์ด์ค๋ฅผ ์ฌ์ฉํ ๋ Java 8์์ ๋์ ๋ default method๋ฅผ ํ์ฉํ๋ฉด ๊ธฐ์กด ์ฝ๋๋ฅผ ์ข ๋ ๊น๋ํ๊ณ ํจ์จ์ ์ผ๋ก ์ฌ์ฉํ ์ ์๋ค.
Optional ์ ๊ฑฐํ๊ธฐ
Spring Data JPA์ findByXX ๋ฉ์๋๋ ๊ธฐ๋ณธ์ ์ผ๋ก Optional์ ๋ฐํํ๋ค. ์ด๋ก ์ธํด ๋น์ฆ๋์ค ๋ก์ง์์ Optional ์ฒ๋ฆฌ๋ฅผ ์ํ ์ถ๊ฐ์ ์ธ ์์ ์ด ํ์ํ๊ฒ ๋๋๋ฐ, ์ด๋ด ๋ default ๋ฉ์๋๋ฅผ ํ์ฉํ๋ฉด ์ด ๋ฌธ์ ๋ฅผ ์ฐ์ํ๊ฒ ํด๊ฒฐํ ์ ์๋ค.
public interface UserRepository extends JpaRepository<User, Long> {
// Default ๋ฉ์๋๋ฅผ ์ฌ์ฉํ์ฌ findById์ Optional์ ๋ด๋ถ์ ์ผ๋ก ์ฒ๋ฆฌ
default User findUserById(Long id) {
return findById(id).orElseThrow(() -> new DataNotFoundException("User not found with id: " + id));
}
}
๋ฉ์๋๋ช ๊ฐ์ํํ๊ธฐ
Spring Data JPA๋ฅผ ์ฌ์ฉํ๋ค ๋ณด๋ฉด ๋ณต์กํ ์ฟผ๋ฆฌ ๋๋ฌธ์ ๋ฉ์๋๋ช ์ด ๊ธธ์ด์ ธ ๊ฐ๋ ์ฑ์ ํด์น๋ ๊ฒฝ์ฐ๊ฐ ์๋ค. ์ด๋ด ๋๋ default ๋ฉ์๋๋ฅผ ํ์ฉํ๋ฉด ๊ธด ๋ฉ์๋๋ช ์ ๊ฐ๊ฒฐํ๊ณ ๋ช ํํ๊ฒ ํํํ ์ ์๋ค.
public interface ProductRepository extends JpaRepository<Product, Long> {
// ๊ธฐ์กด์ ๊ธด ์ฟผ๋ฆฌ ๋ฉ์๋
List<Product> findAllByCategoryAndPriceGreaterThanEqualAndPriceLessThanEqualOrderByPriceAsc(String category, BigDecimal minPrice, BigDecimal maxPrice);
// Default ๋ฉ์๋๋ฅผ ์ฌ์ฉํ์ฌ ๊ฐ๊ฒฐํ ๋ฉ์๋๋ช
์ ๊ณต
default List<Product> findProductsByCategoryAndPriceRange(String category, BigDecimal minPrice, BigDecimal maxPrice) {
return findAllByCategoryAndPriceGreaterThanEqualAndPriceLessThanEqualOrderByPriceAsc(category, minPrice, maxPrice);
}
}
๋น์ฆ๋์ค ๋ก์ง ํตํฉ
์ฌ๋ฌ ๊ธฐ๋ณธ ์ ๊ณต ๋ฉ์๋๋ฅผ ํ๋์ ๊ณ ์ฐจ ์์ ์ผ๋ก ๊ฒฐํฉํ ์๋ ์๋ค. ๋ค๋ง Spring Data JPA์ Repository๋ Data Access Layer์ ์ผ๋ถ๋ก, ๋ฐ์ดํฐ๋ฒ ์ด์ค์์ ์ํธ์์ฉ๋ง์ ๋ด๋นํ๋ ๊ฒ์ด ์ผ๋ฐ์ ์ด๊ธฐ ๋๋ฌธ์ ์ด ๋ถ๋ถ์ ์๋น์ค ๋ ์ด์ด์์ ์ฒ๋ฆฌํ๋ ๊ฒ์ด ์ผ๋ฐ์ ์ด๋ค.
public interface UserRepository extends JpaRepository<User, Long> {
// ์ฌ์ฉ์ ID๋ก ์ฌ์ฉ์๋ฅผ ์ฐพ๊ณ , ์กด์ฌํ ๊ฒฝ์ฐ ์ฐ๋ฝ์ฒ ์ ๋ณด๋ฅผ ์
๋ฐ์ดํธํ๋ ๋ฉ์๋
default void updateUserContact(Long userId, String newContact) {
findById(userId).ifPresent(user -> {
user.setContact(newContact);
save(user);
});
}
}
์ฃผ์ํด์ผ ํ ์
์ฝํ๋ฆฐ์ ์ฌ์ฉํ๋ ๊ฒฝ์ฐ์๋ ์กฐ๊ธ ๋ฌ๋ผ์ง๋ค. ์ฝํ๋ฆฐ์์๋ ์๋ฐ์ default method๋ฅผ ์ง์ ์ง์ํ์ง ์๋๋ค. ๋ค์ ๋งํด ์ฝํ๋ฆฐ์ ์ธํฐํ์ด์ค์์๋ ๊ธฐ๋ณธ ๊ตฌํ์ ๋ฉ์๋์ ์ ๊ณตํ ์ ์์ง๋ง, ์ด๋ ์๋ฐ์ default method์ ๋์ผํ ๋ฐฉ์์ผ๋ก ์๋ํ์ง ์๋๋ค๋ ๊ฒ์ ์๋ฏธํ๋ค.
- ์๋ฐ์ ์ปดํ์ผ๋ฌ๋ ์ธํฐํ์ด์ค์ ์ ์ธ๋ default method๋ฅผ 'interface' ํด๋์ค ํ์ผ์ ์ง์ ํฌํจ์ํค๋ฉฐ, ์ด ๋ฉ์๋๋ค์ ์ผ๋ฐ ์ธ์คํด์ค ๋ฉ์๋์ฒ๋ผ 'invokespecial' ๋ช ๋ น์ด๋ฅผ ์ฌ์ฉํ์ฌ ํธ์ถ๋๋ค.
- ์ฝํ๋ฆฐ ์ปดํ์ผ๋ฌ๋ ๊ฐ ๋ฉ์๋์ ๋ํด ์คํํฑ ๋ฉ์๋๋ฅผ ์์ฑํ๊ณ , ์ด๋ค์ 'DefaultImpls'๋ผ๋ ๋ด๋ถ ํด๋์ค์ ํฌํจ์ํจ๋ค. ์ธํฐํ์ด์ค๋ฅผ ๊ตฌํํ๋ ํด๋์ค์์๋ ์ด๋ฌํ ์คํํฑ ๋ฉ์๋๋ฅผ ํธ์ถํ์ฌ default method์ ๊ธฐ๋ฅ์ ์ฌ์ฉํ๋ค.
์ค์ ๋ก ์ฝํ๋ฆฐ ํ๊ฒฝ์์ JpaRepository๋ฅผ ์์ํ๋ ์ธํฐํ์ด์ค์ ๋ฉ์๋ ๊ตฌํ๋ถ๋ฅผ ํฌํจํ๋ฉด, ์ปดํ์ผ ๊ณผ์ ์์ ๋ค์๊ณผ ๊ฐ์ ์๋ฌ๊ฐ ๋ฐ์ํ ์ ์๋ค.
No property betweenOsVer found for type ${EntityName}
์ด๋ Spring Data JPA๊ฐ "์ฟผ๋ฆฌ ๋ฉ์๋" ๊ธฐ๋ฅ์ ํตํด JpaRepository๋ฅผ ์์ํ ์ธํฐํ์ด์ค์ ๋ฉ์๋ ์ด๋ฆ์ ๊ธฐ๋ฐ์ผ๋ก ์ฟผ๋ฆฌ๋ฅผ ์์ฑํ๊ธฐ ๋๋ฌธ์ด๋ค. ์ด ๊ธฐ๋ฅ์ ํ์ฉํ๋ ค๋ฉด ๋ฉ์๋ ์ด๋ฆ์ด find…By, read…By, count…By ๋ฑ ์ฌ์ ์ ์ ์๋ ๋ค์ด๋ฐ ๊ท์น์ ๋ฐ๋ผ์ผ ํ๋๋ฐ, ์ฌ์ฉ์๊ฐ ์ง์ ์ฟผ๋ฆฌ๋ฅผ ์ ์ํด์ผ ํ๋ ๊ฒฝ์ฐ๋ฅผ ๊ณ ๋ คํด default method๋ "์ฟผ๋ฆฌ ๋ฉ์๋" ๋์์์ ์ ์ธ๋์ด ์๋ค. ํ์ง๋ง ์ฝํ๋ฆฐ์ default method๋ฅผ ์ง์ํ์ง ์๊ธฐ ๋๋ฌธ์ ๋ชจ๋ ๋ฉ์๋์ "์ฟผ๋ฆฌ ๋ฉ์๋"๊ฐ ์ ์ฉ๋๋ฉฐ, ๋ค์ด๋ฐ ๊ท์น์ ๋ฐ๋ฅด์ง ์๋ ๋ฉ์๋๋ ์ปดํ์ผ ์๋ฌ๊ฐ ๋ฐ์ํ๋ค.
๊ฒฐ๊ตญ, ์ฝํ๋ฆฐ์์ JpaRepository๋ฅผ ์์ํ๋ ์ธํฐํ์ด์ค์ ๋ฉ์๋ ๊ตฌํ๋ถ๋ฅผ ํฌํจํ๋ ค๋ฉด, ์๋ฐ์ default method์ ๊ฐ์ ๋ฐฉ์์ผ๋ก๋ ์ฌ์ฉํ ์ ์๋ค๋ ๋ง์ด๋ค.
์ฝํ๋ฆฐ์์ JpaRepository dafult method๋ฅผ ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ์ ๋ํ ๋ ์์ธํ ๋ด์ฉ์ ์๋์ ๊ธ์ ์ฐธ๊ณ ํ๋ฉด ์ข์ ๊ฒ ๊ฐ๋ค.