Spring data jpa
๊ฐ์
Spring Data JPA๋ฅผ ์ ๊ทธ๋ ์ด๋ ํ๋ ๊ณผ์ , ๋๋ ์ ๊ทธ๋ ์ด๋ ํ ์ดํ์ ๋ฐ๊ฒฌ๋ ์ด์์ ํด๊ฒฐ ๋ฐฉ์์ ์ ๋ฆฌํ๋ค.
์ข
์์ฑ ๋ถ์
Jakarta Persistence 3.1 (PDF) / Jakarta EE Platform 10
Spring Boot 3.0.1 (org.springframework.boot:spring-boot:3.0.1)
Spring Boot Starter Data JPA 3.0.1 (org.springframework.boot:spring-boot-starter-data-jpa:3.0.1)
Spring Data JPA 3.0.0 (org.springframework.data:spring-data-jpa:3.0.0)
Spring Data 2022.0.0
Jakarta Annotation API 2.1.1 (jakarta.annotation:jakarta.annotation-api:2.1.1)
Spring ORM 6.0.3 (org.springframework:spring-orm:6.0.3)
Hibernate 6.1.6 (org.hibernate.orm:hibernate-core:6.1.6.Final)
Jakarta Persistence API 3.1.0 (jakarta.persistence:jakarta.persistence-api:3.1.0)
Jakarta Transaction API 2.0.1 (jakarta.transaction:jakarta.transaction-api:2.0.1)
Hibernate 6์์ ๋์ฒด ๋ญ๊ฐ ๋ฌ๋ผ์ก๊ธธ๋?
์ ์ฒด์ ์ธ ๋ณ๊ฒฝ์ฌํญ์ ๋ํด์๋ Hibernate 6.0 Release Announcement๊ณผ Migration Guide๋ฅผ ์ฐธ๊ณ ํ๋ผ.
@OneToOne ๋งคํ ์ปฌ๋ผ์ UNIQUE ์ ์ฝ ์กฐ๊ฑด ์๋ ์์ฑ
์ด์ ๋ฒ์ ์์๋ @OneToOne ๋งคํ๋ ์ปฌ๋ผ์ ๋ํด ๋ฐ์ดํฐ๋ฒ ์ด์ค UNIQUE ์ ์ฝ ์กฐ๊ฑด์ ๋ง๋ค์ง ์์์ง๋ง, 6.2 ๋ฒ์ ๋ถํฐ๋ UNIQUE ์ ์ฝ ์กฐ๊ฑด์ด ์๋์ผ๋ก ์์ฑ๋๋ค. (Hibernate DDL ์คํค๋ง ์๋ ์์ฑ ๊ธฐ๋ฅ์ผ๋ก ํ ์ด๋ธ์ ์์ฑํ๋ ๊ฒฝ์ฐ์ ํด๋น)
๋ง์ฝ ๋งคํ๋ ์ํฐํฐ์ ๋ํด ๋ ผ๋ฆฌ์ Soft-delete ๊ธฐ๋ฅ์ ์ฌ์ฉ์ค์ด๋ผ๋ฉด (ex. is_used, deleted ๋ฑ์ ๋นํ์ฑํ/์ญ์ ํ๋๊ทธ๋ฅผ ์ฌ์ฉํ๊ณ ์๋ ๊ฒฝ์ฐ) ํด๋น ์ปฌ๋ผ์ ์ค๋ณต ๊ฐ์ด ์กด์ฌํ ์๋ ์๊ธฐ ๋๋ฌธ์ Hibernate DDL ์๋ ์์ฑ์ ์ด์ฉํ ๋ ๋ฌธ์ ๊ฐ ๋ฐ์ํ ์ ์๋ค.
์ ํ๋ฆฌ์ผ์ด์ ์ ๋ฌธ์ ๊ฐ ๋ฐ์ํ๋ ๊ฒฝ์ฐ @jakarta.persistence.ForeignKey(NO_CONSTRAINT)๋ฅผ ์ฌ์ฉํ์ฌ UNIQUE ์ ์ฝ ์กฐ๊ฑด ์์ฑ์ ๊ฑด๋ ๋ธ ์ ์๋ค.
๋๋, ๊ธฐ์กด์ @OneToOne ๋งคํ์ @ManyToOne + @UniqueConstraint๋ก ๋ณ๊ฒฝํ ์๋ ์๋ค.
SQL์ ์์ฑํ๋ ๋ด๋ถ ๋ฐฉ์์ด ๋ฌ๋ผ์ก์ด์
Hibernate 5๊น์ง๋ Criteria API๊ฐ ๋จผ์ JPQL/HQL๋ก ๋ณํ๋ ํ, ์ด๋ก๋ถํฐ SQL์ ์ง์ ์์ฑํ๋ ๊ตฌ์กฐ์๋ค.
Hibernate 6๋ถํฐ๋ SQL์ AST(Abstract Syntax Tree)ํํ๋ก ์ถ์ํํ SQM(Semantic Query Model)์ด ๋์ ๋์๋ค. Criteria API๋ JPQL/HQL์ด๋ ๋จผ์ SQM์ผ๋ก ๋ณํ๋๊ณ , SQM ๋ชจ๋ธ์ ์ผ์ ํ ๊ท์น์ ๋ฐ๋ผ SQL ๊ตฌ๋ฌธ์ผ๋ก ๋ณํ๋๋ค.
org.hibernate.orm.query.sqm.ast ๋ก๊ฑฐ์ ๋ก๊น ๋ ๋ฒจ์ debug๋ก ๋ฐ๊พธ๋ฉด SQL AST๊ฐ ์ด๋ป๊ฒ ๋ง๋ค์ด์ง๋์ง ๋ก๊ทธ๋ก ํ์ธํ ์ ์๋ค.
ํ์ง๋ง SQM์ ์ ๊ท ๋์ ์ผ๋ก ์ธํด SQM์ ๋ง๋๋ ๊ณผ์ , ๋๋ SQM์ SQL๋ก ๋ณํํ๋ ๊ณผ์ ์ด ์์ง ์์ ํ๋์ง ์์ ๊ฒ์ผ๋ก ๋ณด์ธ๋ค. ์ด์ ๋ฐ๋ผ ์์ฑ๋ SQL์ด ๊ธฐ๋ํ SQL๊ณผ ๋ค๋ฅธ ์ฌ๋ฌ ์ผ์ด์ค๊ฐ ๋ฐ๊ฒฌ๋๊ณ ์๋ ์ํฉ์ด๋ค.
ํ ์ค ์์ฝ: Hibernate 6๋ก ์ค๋ฉด์ SQL์ ์์ฑํ๋ ๋ด๋ถ ๋ก์ง์ด ์์ ํ ๋ณ๊ฒฝ๋์๊ณ , ์์ง๊น์ง ์์ ํ ๋์ง ์์ ์ฌ๋ฌ ๋ฒ๊ทธ๊ฐ ์กด์ฌํ๋ค.
์ด์
๋ง์ฝ Hibernate์ ๋ฒ๊ทธ ๋๋ ์ด์๋ผ๊ณ ์๊ฐ๋๋ ๊ฒฝ์ฐ Hibernate ORM Issue Board์์ ๋น์ทํ ์ด์๊ฐ ๋ฆฌํฌํธ ๋ ๊ฒ์ด ์๋์ง๋ถํฐ ํ์ธํด๋ณด์.
@Where๋ฅผ ์ฌ์ฉํ ์กฐ์ธ ์ฟผ๋ฆฌ ์กฐ๊ฑด์ด ์ํ๋ ๋๋ก ๋ง๋ค์ด์ง์ง ์์
๋น์ทํ ์ด์: @OneToMany relationship with @Where on child table generates wrong sql (HHH-15902)
2022-12-17 ๋ฆฌํฌํธ ๋ ์ดํ ์์ง ํด๊ฒฐ๋์ง ์์ ์ด์
๋ง๋ค์ด์ง๋ SQL๋ฌธ์ ์กฐ๊ฑด์ ์์น๊ฐ ๋ฌ๋ผ์ ธ์, ์ํ๋ LEFT OUTER JOIN์ด ์๋ INNER JOIN์ฒ๋ผ ๋์ํ๊ฒ ๋์ด ๋ฒ๋ฆผ
๋ฐ๋ชจ ํ๋ก์ ํธ
์ ๋ง Hibernate 6.1์ ๋ฌธ์ ์ธ ๊ฒ์ธ์ง ํ์ธํด ๋ณด๊ธฐ ์ํด์, ๊ธฐํ ๋ค๋ฅธ ์ข ์์ฑ ์์ด Hibernate Core๋ง ๊ฐ์ง๊ณ ๋ฐ๋ชจ ํ๋ก์ ํธ๋ฅผ ๊ฐ๋ฐํ์ฌ ํ ์คํธ ํด ๋ณด์๋ค.
ํ ์คํธ ๋ฐฉ๋ฒ: docker-compose ์ด์ฉํ์ฌ ๋ก์ปฌ MySQL 5.7 ๋์๋ ํ Application.kt์ main() ํจ์ ์คํ
ํ ์คํธ ๊ฒฐ๊ณผ: Hibernate 5.6 โ 6.1 ์ ๊ทธ๋ ์ด๋ ์ดํ Fetch Join ๋ฐฉ์๊ณผ Entity Graph ๋ฐฉ์ ์กฐํ์ ๋ง๋ค์ด์ง๋ SQL ๊ตฌ๋ฌธ์ด ๋ฌ๋ผ์ก๋ค๋ ๊ฒ, ๊ทธ๋ฆฌ๊ณ ๊ทธ๋ก ์ธํด ์กฐํ ๊ฒฐ๊ณผ๊ฐ ๋ฌ๋ผ์ก๋ค๋ ๊ฒ์ ํ์ธํ ์ ์์๋ค.
๊ตฌ์ฒด์ ์ผ๋ก๋, Entity Graph๋ฅผ ์ด์ฉํด์ @OneToOne ์ฐ๊ด๊ด๊ณ๋ฅผ fetch Join ํ๋ ๊ฒฝ์ฐ์ @Entity ํด๋์ค์ ๋ถ์ธ @Where clause๊ฐ ๋ฌด์๋๋ ๊ฒ์ผ๋ก ๋ณด์ธ๋ค.
@DiscriminatorValue๋ฅผ ์ฌ์ฉํ ์ํฐํฐ์ ์กฐ์ธ ์ฟผ๋ฆฌ๊ฐ ์๋ชป ๋ง๋ค์ด์ง
๊ด๋ จ ๋ฌธ์: Hibernate 6 Wrong query generated with @DiscriminatorValue
Stackoverflow: Hibernate 6 Wrong query generated
2022-12-06 ๋ฆฌํฌํธ ๋ ์ดํ ์์ง ํด๊ฒฐ๋์ง ์์ ์ด์
์กฐ์ธ์ ON ์ ์ ๋ค์ด๊ฐ๋ ์กฐ๊ฑด์ด ๋ฐ๊นฅ WHERE ๋ฌธ์ผ๋ก ๋น ์ ธ๋์จ๋ค๋ ์ ์์ @Where๋ฅผ ์ฌ์ฉํ ์ฟผ๋ฆฌ๊ฐ ์๋ชป ๋ง๋ค์ด์ง๋ ์ด์์ ๋งค์ฐ ์ ์ฌํ๋ค. (ํจ๊ป fix๋ ๊ฐ๋ฅ์ฑ๋ ์์ ์ ์๊ฒ ๋ค.)
Useful Articles
Spring Data ๊ณต์ ์์ ์ฝ๋๋ spring-data-examples GitHub Repository๋ฅผ ์ฐธ๊ณ ํ์.
Hibernate ๊ณต์ ์๋ฃ๋ค์ Hibernate ORM GitHub Wiki๋ฅผ ์ฐธ๊ณ ํ์.
Last updated