JPA @OneToMany - targetEntity
Objective
๐ก JPA์ @OneToMany ์ฐ๊ด ๊ด๊ณ์์ ์ฐ๊ด ์ํฐํฐ๊ฐ open class ์ธ ๊ฒฝ์ฐ read-only ์ปฌ๋ ์ ์ ์ฌ์ฉํ์ง ๋ชปํ๊ณ Mutable ์ปฌ๋ ์ ์ ์ฌ์ฉํ๋๋ก ํ๋๋ฐ, ์์ธ๊ณผ read-only ์ปฌ๋ ์ ์ ์ฌ์ฉํ ์ ์๋ ํด๊ฒฐ ๋ฐฉ์์ ๊ณต์ ํฉ๋๋ค.
Background
build.gradle.kts
allOpen {
annotation("javax.persistence.Entity")
annotation("javax.persistence.MappedSuperclass")
annotation("javax.persistence.Embeddable")
}
OrderEntity.kt
OrderProductEntity.kt
Error Message
- One To Many ์์ฑ ๊ฐ์ ๋ฐ์ดํฐ๋ ‘? extends OrderProductEntity’ ๊ฐ ๋ ์ ์๋ค.
Collection has neither generic type or OneToMany.targetEntity() defined:
moonee.order.storage.db.core.entity.OrderEntity.orderProductList
- ์ปฌ๋ ์ ์ ์ ๋ค๋ฆญ ํ์ ์ ๊ฐ์ง ์ ์๊ฑฐ๋, OneToMany์ targetEntity๋ฅผ ์ ์ํด์ผ ํ๋ค.
์์ธ
public interface List<out E> : Collection<E>
- List๋ ๊ณต๋ณ์ฑ์ ๊ฐ์ง๋ค.
- ๊ณต๋ณ์ ์ด๋ค ?
- ํ์ ํ์ ๊ด๊ณ๊ฐ ์ ์ง๋๋ค.
- A๊ฐ B์ ํ์ ํ์ ์ผ ๋, List<A>๊ฐ List<B>์ ํ์ํ์ ์ด๋ค.
- A๊ฐ B์ ํ์ ํ์ ์ผ ๋, List<A> ํ์ ์ ๊ฐ์ด ๋ค์ด๊ฐ ์๋ฆฌ์ List<B> ํ์ ์ ๊ฐ์ ์ฌ์ฉํ ์ ์๋ค.
- ์ฝํ๋ฆฐ์ ํด๋์ค๋ ๊ธฐ๋ณธ์ ์ผ๋ก final์ด๋, allOpen ์ค์ ์ ํตํด @Entity ํด๋์ค๋ ์์ ๊ฐ๋ฅํ ํด๋์ค์ด๋ค.
- orderProductList์ ํ์ ์ List<OrderProductEntity> ๋ก ํ๊ฒ ๋๋ฉด, List<OrderProductEntity> ํ์ ์ด ๋ค์ด์ฌ ์๋, OrderProductEntity ๋ฅผ ์์ํ List<? extends OrderProductEntity ํ์ ์ด ๋ค์ด์ฌ ์๋ ์๋ค.
- ๊ณต๋ณ์ ์ด๋ค ?
- Hibernate๋ Collection ํ์
์ ๋ํด Generic ํ์
์ ํ์ฉํ์ง ์๋๋ค.
- ๋ฐํ์์์ ํ์ ์ด ๋์ ์ผ๋ก ๋ฐ๋ ์ ์๋ ๊ฒ์ ์ง์ํ์ง ์๋๋ค.
- ๋ญ๊ฐ ๊ด๋ จ๋ ๊ฒ ๊ฐ์ ๋ฌธ์๋ฅผ ๋ฐ๊ฒฌํ๋๋ฐ ์ ํํ ํด์์ด ์ด๋ ต์ต๋๋ค. (์ฐธ๊ณ )
Solution
Solution 1. MutableList๋ฅผ ์ฌ์ฉํ๋ค ?
- Intellij ์์๋ ์ด ๊ฒฝ์ฐ, MutableList๋ฅผ ์ฌ์ฉํ๋ผ๊ณ ๊ถ๊ณ ํ๋ค.
- ์ MutableList๋ ๋ ๊น?
- ์๋ํ๋ฉด…. MutableList๋ ๋ฌด๊ณต๋ณ์ด๋ค. out ํค์๋๊ฐ ์์.
⇒ ํ์ง๋ง orderProductList๋ ๋ณ๊ฒฝ๋์ง ์๋ ๋ฐ์ดํฐ์ด๊ธฐ ๋๋ฌธ์ MutableList๋ก ์ฌ์ฉํ๊ณ ์ถ์ง ์๋ค. (ํ๋ฝ)
Solution 2. Entity๋ฅผ ์์ ๋ถ๊ฐ๋ฅํ๊ฒ ํ๋ค ?
- OrderProductEntity๊ฐ open class ์ด๊ธฐ ๋๋ฌธ์, List ๋ฅผ ์ฌ์ฉํ๋ฉด ์ ํํ ์ด๋ค ํ์ ์ด ๋ค์ด์ฌ์ง ์ ์ ์์ผ๋ ๋ฐ์ํ๋ ์ค๋ฅ๋ผ๊ณ ํ๋จํด์ allOpen ์ค์ ์ ์ง์๋ดค๋ค.
- …. ๊ทธ๋ฌ๋๊น ํด๊ฒฐ์ ๋๋ค.
- ํ์ง๋ง, ๋ช ์ฃผ ์ ์ผ๋ธ๋์ JPA ์ง์ฐ๋ก๋ฉ ๋ฝ๊ฐ๊ธฐ ์์ ๋ค์๋ฏ์ด, @~ToOne ๊ด๊ณ์์ ์ง์ฐ๋ก๋ฉ์ ํ ๋ JPA๋ ํด๋น ํด๋์ค๋ฅผ ์์ํ์ฌ ํ๋ก์๋ฅผ ๋ง๋๋ ๋ฐฉ์์ผ๋ก ์ง์ฐ ๋ก๋ฉ์ ํ๋ค๊ณ ํ๋ค.
⇒ ๊ทธ๋์ allOpen์ ์ง์ฐ๋ ๊ฑด ์ข์ ํด๊ฒฐ์ฑ ์ ์๋๋ค.
Solution 3. val ์ ์ฌ์ฉํ๋ค.
@OneToMany(cascade = [CascadeType.ALL], fetch = FetchType.LAZY, mappedBy = "order")
val orderProductList: List<OrderProductEntity>
- var ๋์ val ๋ฅผ ์ฌ์ฉํ๋ฉด ์์ฑํ ๋ ์ด๊ธฐํ๋๊ณ ๋ฐ๋์ง ์๊ธฐ ๋๋ฌธ์ List ๋ฅผ ์ฌ์ฉํ ์ ์๋ ๊ฒ ๊ฐ์๋ค.
⇒ ํ์ง๋ง OrderProductEntity ๋ order ๋๋ orderId ๋ฅผ ๊ฐ์ง๊ณ ์๊ธฐ ๋๋ฌธ์, OrderEntity๋ฅผ ์์ฑํ๋ฉด์ ๋์์ OrderProductEntity๋ฅผ ์์ฑํ ์ ์๊ธฐ ๋๋ฌธ์ val ๋ฅผ ์ฌ์ฉํ๊ธฐ ์ด๋ ต๋ค.
Solution 4. targetEntity ์์ฑ์ ์ด์ฉํ๋ค.
๋ฒ์ญ / (์ ํ ์ฌํญ) ์ฐ๊ฒฐ ๋์์ธ ์ํฐํฐ ํด๋์ค์ ๋๋ค. ์ปฌ๋ ์ ์์ฑ์ด Java ์ ๋ค๋ฆญ์ ์ฌ์ฉํ์ฌ ์ ์๋ ๊ฒฝ์ฐ์๋ง ์ ํ ์ฌํญ์ ๋๋ค. ๋ฌ๋ฆฌ ์ง์ ํด์ผ ํฉ๋๋ค. ์ ๋ค๋ฆญ์ ์ฌ์ฉํ์ฌ ์ ์๋ ๊ฒฝ์ฐ ์ปฌ๋ ์ ์ ๋งค๊ฐ ๋ณ์ํ๋ ์ ํ์ด ๊ธฐ๋ณธ๊ฐ์ ๋๋ค.
- ๊ทธ๋ ๋ค๊ณ ํฉ๋๋ค. ์ฌ์ฉํ๋๊น ํด๊ฒฐ๋์์ต๋๋ค.
- ์๋ง JPA ์๊ฒ OrderProductEntity ๋๋ ? extends OrderProductEntity ํ์ ๋ค ์ค ์ด๋ค ํ์ ์ ์ฌ์ฉํ ์ง ์ ํํ๊ฒ ์๋ ค์ฃผ๋ ๊ฒ์ด๋ ํด๊ฒฐ์ด ๋์๋ค๊ณ ์ดํดํ์ต๋๋ค.
๊ฒฐ๋ก
- targetEntity ์์ฑ์ ์ด์ฉํ์
- Hibernate์ implicit Polymorphism ์ ๋ํด ์กฐ๊ธ ๊ณต๋ถํด๋ณด๊ณ ์ถ์๋ฐ ์ด๋ ต๋ค. (๊ฐ์ด ๋ณด์ค ๋ถ ๋ชจ์งํฉ๋๋ค)