๋ชฉ๋กBack-end/JPA (7)
DevLog ๐ถ
๐ฑ ๋ค์ด๊ฐ๊ธฐ ์ ์๋ ์ ์ผ๋ ๊ธ์ธ๋ฐ, ์์ฆ ๋ธ๋ก๊ทธ๋ฅผ ๋๋ฌด ์ ์ด ๊ฒ ๊ฐ์์ ์ค๋๋ง์ ์ฌ๋ฆฌ๋ ๊ธ ๐ถ ํผ์ ๊ณต๋ถํ ๊ฒธ ์์ฑํ ๊ธ์ด์์ด์ ๋ค์ ์ค๋ช ์ด ๋ถ์กฑํฉ๋๋ค...! ๐ฑ ์ํฐํฐ ์๊ฐ @Entity @EntityListeners(AuditingEntityListener.class) public class User { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @Column(nullable = false) @CreatedDate private LocalDateTime createdAt; @LastModifiedDate private LocalDateTime updatedAt; User ํด๋์ค๋ ์ฌ์ฉ์์ ๋ํ ์ํฐํฐ์ด๋ฉฐ, id..
๐ฑ ๋ค์ด๊ฐ๊ธฐ ์ JPA์์ @OneToMany ๋จ๋ฐฉํฅ ๋งคํ๋ณด๋ค๋ ๋ค๋์ผ ์๋ฐฉํฅ ๋งคํ์ ๊ถ์ฅํ๋ค๋ ๋ง์ ๋ณด์์ ๊ฒ์ด๋ค. ํ์ง๋ง, ๊ฐ์ฒด์งํฅ์ผ๋ก ์ฝ๋๋ฅผ ์ค๊ณํ๋ค ๋ณด๋ฉด ๋ค๋์ผ์ ์ํฉ๋ณด๋ค๋ 1์ธ ์ํฐํฐ๋ฅผ ๊ธฐ์ค์ผ๋ก N์ธ ์ํฐํฐ๋ฅผ ์กฐํํ๋ ๊ฒฝ์ฐ๊ฐ ๋ ๋ง๊ณ , (์ ์ด๋ ๋ด ๊ฒฝํ์์๋ ๊ทธ๋ฌ๋ค) N์ธ ์ํฐํฐ๊ฐ ๊ตณ์ด 1์ธ ์ํฐํฐ์ ๋ํ ์ ๋ณด๋ฅผ ๋ชฐ๋ผ๋ ๋๋ ์ ์ด ๋ง์๋ค. ๊ทธ๋ฌ๋ค ๋ณด๋ ์์ฐ์ค๋ฝ๊ฒ ์ผ๋๋ค ๋จ๋ฐฉํฅ ๋งคํ์ ๋ง์ด ์ฌ์ฉํ์๋๋ฐ, ์ ๊ทธ๋ฌ๋ ๊ฒ์ธ์ง ๊ถ๊ธํด์ ๋๋ฆ๋๋ก ์คํ์ ํด๋ณด๊ณ ์ ํ๋ค. (ex. ๊ฒ์๊ธ๊ณผ ๊ฒ์๊ธ ์ด๋ฏธ์ง์ ๊ด๊ณ์์, ๊ฒ์๊ธ ์ด๋ฏธ์ง๋ฅผ ๊ธฐ์ค์ผ๋ก ๊ฒ์๊ธ ์ ๋ณด๋ฅผ ์ฐพ์์ค๋ ๊ฒ๋ณด๋ค๋ ๊ฒ์๊ธ์ ๊ธฐ์ค์ผ๋ก ๊ฒ์๊ธ ์ด๋ฏธ์ง ์ ๋ณด๋ฅผ ๊ฐ์ ธ์ค๋ ๊ฒ ๋ ๋ง์์) ๐ฑ ๊ธฐ๋ณธ ์ํฐํฐ ์ค๊ณํ๊ธฐ @Entity class Board( @Id @..
๐ฑ JPA ๊ธฐ๋ณธ ํค ์์ฑ ์ ๋ต JPA์์ ์ ๊ณตํ๋ ๊ธฐ๋ณธ ํค ์์ฑ ์ ๋ต์ ํฌ๊ฒ 5๊ฐ์ง๋ก ๋๋์ด์ง๋ค. - TABLE, SEQUENCE, IDENTITY, UUID, AUTO ๊ฐ ์ ๋ต์ ๋ํด์ ํ๋์ฉ ์์๋ณด๋๋ก ํ์. ๐ฑ TABLE ๐ก Indicates that the persistence provider must assign primary keys for the entity using an underlying database table to ensure uniqueness. - ๋ฐ์ดํฐ๋ฒ ์ด์ค ํ ์ด๋ธ์ ์ฌ์ฉํ์ฌ ์ํฐํฐ์ ๊ธฐ๋ณธ ํค๋ฅผ ํ ๋นํด์ผ ํ๋ค. ๐ฌ ์ํฐํฐ ์ค์ @Entity class User( @Id @GeneratedValue(strategy = GenerationType.TABLE) val id: Lon..
๐ฑ ๋ค์ด๊ฐ๊ธฐ ์ ์ง๋ ํฌ์คํ ์์๋ CascadeType.REMOVE์ ๋ํด์ ์ค์ ์ ์ผ๋ก ์์๋ดค์๋๋ฐ, ์ด๋ฒ์๋ orphanRemoval=true ์ต์ ์ ๋ํด์ ํ ๋ฒ ์์๋ณด์. ์ํฐํฐ ์ธํ ์ ์ง๋ ๋ฒ๊ณผ ๊ฑฐ์ ๋์ผํ๊ธฐ ๋๋ฌธ์ ๋ณํ๊ฐ ์๊ธด ๋ถ๋ถ์ ๋ํด์๋ง ๋ฐ๋ก ์ง๋๋ก ํ๊ฒ ๋ค. ๐ฑ ์ํฐํฐ ์์ ํ๊ธฐ ์ด๋ฒ์๋ CascadeType.REMOVE ๋์ ์ orphanRemoval=true๋ฅผ ์ ์ฉํ์. @Entity class Concert( @Id @GeneratedValue(strategy = GenerationType.IDENTITY) val id: Long = 0L, @Column(nullable = false) val name: String, @Column(nullable = false) val ticketLi..
๐ฑ ๋ค์ด๊ฐ๊ธฐ ์ JPA๋ฅผ ๊ณต๋ถํ๋ฉด์ CascadeType.REMOVE์ orphanRemoval = true ์ต์ ์ ๋ํด์ ์ด๋ค ์ฐจ์ด๊ฐ ์๋์ง ์ ๋๋ก ์ธ์งํ ์ ์ด ์๋ ๊ฒ ๊ฐ์์, ์ด๋ฒ์ ๊ณต๋ถํ ๊ฒธ ์ฌ๋ฌ ๊ฐ์ง ํ ์คํธ๋ฅผ ์งํํด๋ณด๋ฉฐ ๋ ์ต์ ์ ์ฐจ์ด๋ฅผ ๊ณต๋ถํด๋ณด์๋ค. ๊ฒฐ๊ณผ์ ์ผ๋ก ๋งํ์๋ฉด Cascade ์ต์ ์ ๋ถ๋ชจ ์ํฐํฐ์ ์์ ์ํฐํฐ์ ์์ ์ํ๋ฅผ ๊ด๋ฆฌํ๋ ๊ฒ์ด๊ณ , orphanRemoval์ ์กฐ๊ธ ๋ ์ธ๋ถ์ ์ผ๋ก ๊ณ ์ ๊ฐ์ฒด์ ๋ํ ๊ด๋ฆฌ๋ผ๋ ์๊ฐ์ด ๋ค์๋ค. ์ง๊ธ๋ถํฐ ์ฌ๋ฌ ์ผ์คํธ๋ฅผ ํ ์คํธํ๋ฉฐ ํ๋์ฉ ์์๋ณด์. ๐ฑ ์ํฐํฐ ์ธํ ํ๊ธฐ 1:N ๊ด๊ณ๋ฅผ ๋ด๋นํด์ค '์ฝ์ํธ' ์ํฐํฐ์ '์ฝ์ํธ ํฐ์ผ' ์ํฐํฐ๋ฅผ ์์ฑํ์๋ค. ๋ ์ฌ์ด์ ๊ด๊ณ๋ ์๋ฐฉํฅ์ผ๋ก ์ค์ ํ์์ผ๋ฉฐ, ํ๋์ ์ฝ์ํธ๋ ์ฌ๋ฌ ๊ฐ์ ์ฝ์ํธ ํฐ์ผ์ ๋ณด์ ํ ์ ์๋๋ก ์ค๊ณํ์..
๐ฑ ๋ค์ด๊ฐ๊ธฐ ์ ์ง๋ ํฌ์คํ ์์๋ ์ค์์ ์ํ์ ์ํฐํฐ๋ ์ง์ฐ ๋ก๋ฉํ ์ ์๋ค๊ณ ๋งํ๋ค. ์ด๋, ์ง์ฐ ๋ก๋ฉ์ ์ํ ํ๋ก์ ๊ฐ์ฒด๋ฅผ ์ด๊ธฐํํ๊ธฐ ์ํด ์์์ฑ ์ปจํ ์คํธ๊ฐ ํ์ํ๋ฐ, ์ค์์ ์ํ์ ์ํฐํฐ๋ ์์์ฑ ์ปจํ ์คํธ์ ๊ด๋ฆฌ ๋ฒ์์์ ๋ฒ์ด๋ฌ๊ธฐ ๋๋ฌธ์ด๋ค. ๊ทธ๋ ๋ค๋ฉด, ์ค์์ ์ํ์ ์ํฐํฐ๋ ์ด๋ป๊ฒ ์ฒ๋ฆฌํด์ผ ํ ๊น? ๐ฑ ๊ธ๋ก๋ฒ ํ์น ์ ๋ต์ LAZY์์ EAGER๋ก ์์ ํ๊ธฐ ๊ฐ๋จํ๊ฒ ๋งํ๋ฉด ์ง์ฐ ๋ก๋ฉ์ ์ฌ์ฉํ์ง ๋ง๊ณ , ์ฆ์ ๋ก๋ฉ์ ์ฌ์ฉํ์๋ ๊ฒ์ด๋ค ๐ @Entity @Getter @NoArgsConstructor(access = AccessLevel.PROTECTED) public class Crew { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private ..
๊ธ์์ผ์ ๊ทผ๋กํ๋ฉด์ ๊ตฌ๊ตฌ์ ๊ทผ๋ก ํฌ๋ฃจ๋ค์ ๋์ ๋๋ถ์ JPA๋ฅผ ๋ค์๊ธ ๊ณต๋ถํ๊ฒ ๋๋ค ๐ ๋๋ ์์ ํ๊ฒ ์ ์๋ ๋ด์ฉ์ ์๋์ง๋ผ ์๋๋๋ก ์ ๋ฆฌํด๋ณด๊ณ ์ ํ๋ค. ๐ฑ ์์์ฑ ์ปจํ ์คํธ์ ํธ๋์ญ์ ๐ก ์์์ฑ ์ปจํ ์คํธ๋? ์ํฐํฐ๋ฅผ ์์ํ์ํค๋ ํ๊ฒฝ. EntityManager๋ฅผ ํตํด ์ํฐํฐ๋ฅผ ์ ์ฅํ๊ฑฐ๋ ์กฐํํ๋ฉด ์์์ฑ ์ปจํ ์คํธ์ ๋ณด๊ด๋ ์ํฐํฐ ์ ๋ณด๋ฅผ ๋ฐํ์ผ๋ก ์์ฒญ์ ์ฒ๋ฆฌํ๊ฒ ๋๋ค. EntityManager ์์ฑ ์ 1๊ฐ๊ฐ ๋ง๋ค์ด์ง๋ค. ๐ฌ ํน์ง - ์๋ณ์ ๊ฐ์ผ๋ก ์ํฐํฐ๋ฅผ ๊ตฌ๋ถํ๋ค. - ํธ๋์ญ์ ์ปค๋ฐ ์์ ์ flush. (์ฐ๊ธฐ ์ง์ฐ - ๋ด๋ถ ์ฟผ๋ฆฌ ์ ์ฅ์์ SQL ์ ์ฅ ํ ํ ๋ฒ์ ํ๋ฌ์) - 1์ฐจ ์บ์๋ฅผ ์ฌ์ฉํ๋ค. (์ฒ์์ 1์ฐจ ์บ์์์ ์ํฐํฐ ์กฐํ > ์์ผ๋ฉด DB ์กฐํ > 1์ฐจ ์บ์์ ์ ์ฅํ๋ ํํ = '์์ํ') - ..