JPA #3 ๊ธฐ๋ณธ ์ฌ์ฉ๋ฒ, ์์์ฑ ์ปจํ ์คํธ
by JiwonDev๐ SQL ๋ฐฉ์ธ (Dialect)
๊ฐ ํ์ฌ๋ง๋ค ๋ค๋ฅธ SQL ๋ฌธ๋ฒ์ ์ด๋ป๊ฒ ์ฒ๋ฆฌํ ๊น? (Limit, ROWNUM)
org.hibernate.dialect ๋ฅผ ์ฌ์ฉํ๋ฉด ๋๋ค. JPA์ DB์ ์์กด์ฑ์ ์ต์ํ ํ ์ ์๋ค.
์ฐธ๊ณ ๋ก ์คํ๋ง๋ถํธ๋ฅผ ์ฌ์ฉํ๋ฉด ๋ฒ์ ๋ง๋ค ๊ธฐ๋ณธ์ผ๋ก ์ฌ์ฉํ๋ Hibernate ๋ฒ์ ์ด ๋ค๋ฅด๋ฏ๋ก, ๋ฒ์ ์ ์ค์ ํ ๋ ์ฃผ์ํ์.
Gradle, Maven ์ค์ ๋ฐฉ๋ฒ
Gradle์ application.yml ์ค์ ํ์ผ์์ ์ถ๊ฐํ ์ ์๋ค.
server:
port: 8080
spring:
datasource:
url: jdbc:mysql://...์๋ต
username: ์ ์ ๋ช
password: ๋น๋ฐ๋ฒํธ
driver-class-name: com.mysql.cj.jdbc.Driver
jpa:
hibernate:
dialect: org.hibernate.dialect.MySQL5InnoDBDialect // ์ด๋ฐ ์์ผ๋ก ์ถ๊ฐ๊ฐ๋ฅ
ddl-auto: none
properties:
hibernate:
format_sql: true
data:
web:
pageable:
default-page-size: 10
Maven์ .../resources/META_INF/persistence.xml ์ ๋ง๋ค์ด์ ์ค์ ํ ์ ์๋ค.
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.2"
xmlns="http://xmlns.jcp.org/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_2.xsd">
<!-- ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ด๋ฆ -->
<persistence-unit name="hello">
<properties>
<!-- ํ์ ์์ฑ -->
<property name="javax.persistence.jdbc.driver" value="org.h2.Driver"/>
<property name="javax.persistence.jdbc.user" value="sa"/>
<property name="javax.persistence.jdbc.password" value=""/>
<property name="javax.persistence.jdbc.url" value="jdbc:h2:tcp://localhost/~/test"/>
<!-- H2 DB์ Dialect ์ค์ -->
<property name="hibernate.dialect" value="org.hibernate.dialect.H2Dialect"/>
<!-- ์ต์
-->
<property name="hibernate.show_sql" value="true"/>
<property name="hibernate.format_sql" value="true"/>
<property name="hibernate.use_sql_comments" value="true"/>
<!--<property name="hibernate.hbm2ddl.auto" value="create" />-->
</properties>
</persistence-unit>
</persistence>
๐ JPA ๊ตฌ๋ ๋ฐฉ์
์คํ๋ง ์์ด JPA๋ฅผ ์ฌ์ฉํ๋ค๊ณ ํ๋ฉด, ์๋์ ๊ฐ์ ์ฝ๋๊ฐ ๋์ค๊ฒ ๋๋ค.
public final class MemberService {
public static void main(String[] args) {
/* ์ดํ๋ฆฌ์ผ์ด์
์ด ์์ํ ๋ Factory ์์ฑํ๋ค. */
EntityManagerFactory factory = Persistence.createEntityManagerFactory("hello");
// ๐ญ 1. ์ค๋ ๋์์ ์ฌ์ฉํ EntityManager ๋ฅผ Factory ๋ก ์์ฑํ๊ณ , ํธ๋์ญ์
์ ๋ง๋ ๋ค.
EntityManager entityManager = factory.createEntityManager();
EntityTransaction tx = entityManager.getTransaction();
// ๐ญ 2. JPA๋ฅผ ์ด์ฉํ ๋ชจ๋ ๋ฐ์ดํฐ ๋ณ๊ฒฝ์ ํธ๋์ญ์
์์์๋ง ์คํ๋ ์ ์๋ค.
try {
Member member = new Member();
member.setId(2L);
member.setName("Kim");
entityManager.persist(member);
tx.commit();
} catch (Exception e) {
tx.rollback();
} finally {
// ๐ญ 3. ์ฌ์ฉ์ด ๋๋ EntityManager ๋ฐ๋ฉํ๋ค.
entityManager.close();
}
/* ์ดํ๋ฆฌ์ผ์ด์
์ด ์ข
๋ฃํ ๋ ํ์์์ด์ง Factory ๋ฐํํ๋ค. */
factory.close();
}
}
์ ๋ง ์๋ฐ ์ปฌ๋ ์ ์ ๋ค๋ฃจ๋ ๊ฒ์ฒ๋ผ DB๋ฅผ ๋ค๋ฃฐ ์ ์๋ค.
๋จ์ํ ํธ์๊ธฐ๋ฅ์ด ์๋๋ผ, JPA๋ฅผ ์ฌ์ฉํ๋ฉด commitํ๋ ์์ ์ ๋ณ๊ฒฝ๋ ๋ถ๋ถ์ ๊ฐ์งํ์ฌ SQL ์ฟผ๋ฆฌ๋ฅผ ์์ฑํ๊ธฐ ๋๋ฌธ์ด๋ค.
try {
Member findMember = entityManager.find(Member.class, 1L);
findMember.setName("new_Name"); // ์ด๋ฆ์ ๋ณ๊ฒฝํ์๋ค.
// entityManager.persist(findMember); โก ์ ์ฅํ์ง ์์๋ ์
๋ฐ์ดํธ ์ฟผ๋ฆฌ๊ฐ ๋๊ฐ์ ๋ฐ์๋จ.
tx.commit();
} catch (Exception e) { ... }
์ฝ๋๋ฅผ ๋ณด๋ฉด ์๊ฒ ์ง๋ง, EntityManager๋ ๋ฐ์ดํฐ๋ฒ ์ด์ค Connection์ฒ๋ผ ์ฌ์ฉ๋๋ค.
์ฆ ์ ๋๋ก EntityManager๋ฅผ ๊ณต์ ํด์๋ ์๋๋ค. ํ๋์ ์ค๋ ๋์์ ์ฌ์ฉํ๊ณ , ์ฌ์ฉ์ด ๋๋๋ฉด ๋ฐ๋ฉํด์ผํ๋ค.
๊ทธ ์ด์ ๋ ํธ๋์ญ์ ๋จ์๋ก EntityManager๋ฅผ ์ฌ์ฉํ๊ธฐ ๋๋ฌธ์ด๋ค. ์ฌ๋ฌ ์ค๋ ๋๊ฐ ๋์์ ์ฌ์ฉํ๋ค๋ฉด, ์์์ฑ ์ปจํ ์คํธ์ DB ๊ฐ์ ๋ฐ์ดํฐ ๋๊ธฐํ๊ฐ ๊นจ์ง๊ฒ ๋๋ค. ์ปค๋ฐ์ด ๋ ์ดํ์๋ ์์์ฑ ์ปจํ ์คํธ๋ ๋ฐ๋ฉํ๋ค๊ฐ ์๋กญ๊ฒ ์์ฑํด์ผ ํ๋ค.
๐ ๋ณต์กํ ์กฐํ๋ ์ด๋ป๊ฒ ํ์ฃ ?
๋จ์ํ ์ปฌ๋ ์ ์ฒ๋ผ ๊บผ๋ด๋๊ฒ ์๋๋ผ, ์๋์ ๊ฐ์ด ๋ณต์กํ ์กฐ๊ฑด์ด ์๋ค๋ฉด ์ด๋ป๊ฒ ์ฌ์ฉํ ๊น?
- ID๊ฐ 2์ด์์ด๊ณ , ์ด๋ฆ์ด KIM์ธ ํ์๋ง ๊ฒ์
- ์ ์ฒด ํ์์ค ์ด๋ฆ์์ผ๋ก 100๋ช ๋ง ๊ฒ์
์ด๋ฅผ ์ํด์ JPQL์ด๋ผ๋ ๋ฌธ๋ฒ์ด ์ ๊ณต๋๋ค. ๊ฐ๋จํ ์ฝ๋ ์์ ๋ฅผ ์ ์๋ฉด ์๋์ ๊ฐ๋ค.
try {
List<Member> result = entityManager.createQuery("select m from Member", Member.class)
.getResultList();
tx.commit();
} catch (Exception e) {
๋ค๋ง ์ค์ํ ๊ฒ์ JPQL์ ์ด์ฉํ์ฌ ์ ์ select m from Member๋ DB ํ ์ด๋ธ์ ์์ฒญํ๋ ์ฟผ๋ฆฌ๊ฐ ์๋๋ค. ๊ฐ์ฒด๋ฅผ ๋์์ผ๋ก ํ๋ ๊ฐ์ฒด์งํฅ SQL ๋ฌธ๋ฒ์ด๋ค. ์ฆ ์๋ฏธ ๊ทธ๋๋ก [ Member ๊ฐ์ฒด ] ๋ฅผ ๊ฐ์ ธ์ค๋ ๋ฌธ๋ฒ์ด๊ณ ์ค์ SQL์ ๋ค๋ฅด๊ฒ ๋์ํ๋ค.
JPA๋ ๊ฐ์ฒด(Entity)๋ฅผ ์ค์ฌ์ผ๋ก ๊ฐ๋ฐํ ์ ์๊ฒ ์ ๊ณตํด์ฃผ๋ ๋๊ตฌ์ด๋ค.
๋ชจ๋ DB ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ฒด๋ก ๋ณํํด์ ๊ฒ์ํ๋๊ฑด ์๋นํ ๋นํจ์จ์ ์ด๊ณ , ์ฌ์ค์ ๋ถ๊ฐ๋ฅํ๋ค.
๊ทธ๋์ ํ์ํ ๋ฐ์ดํฐ๋ง DB์ ์์ฒญํ๊ธฐ ์ํด์ JPQL์ด๋ผ๋ ๊ฐ์ฒด ์ ์ฉ SQL๋ฌธ์ ์ถ๊ฐ๋ก ์ ๊ณตํด์ฃผ๋ ๊ฒ์ด๋ค.
๋ค๋ง ์ฌ์ฉ๋ฒ์ SQL ๋ฌธ๋ฒ๊ณผ ๊ฑฐ์ ์ ์ฌํ๋ค. SELECT, FROM, WHERE, GROUP BY, HAVING, JOIN ์ง์
๐ JPA์ ๋น๋ฐ, EntityManager (์์์ฑ ์ปจํ ์คํธ)
JPA๋ฅผ ์กฐ๊ธ์ด๋ผ๋ ๊ณต๋ถํด๋ดค๋ค๋ฉด ์๋์ ๋จ์ด๋ฅผ ์์ฒญ ๋ง์ด ๋ค์ด๋ดค์ ๊ฒ์ด๋ค.
Persistence Context (์์์ฑ ์ปจํ ์คํธ)
- ์ํฐํฐ๋ฅผ ์๊ตฌ ์ ์ฅ ํ๋ ํ๊ฒฝ.
- ์ ํ๋ฆฌ์ผ์ด์ ์ด ๋ฐ์ดํฐ๋ฒ ์ด์ค์์ ๊บผ๋ด์จ ๊ฐ์ฒด๋ฅผ ๋ณด๊ดํ๋ ์ญํ ์ ํ๋ค.
์ค์ ๋ก JPA์์ ์ ์ฅํ ๋ save() ๋ผ๋ ์ด๋ฆ ๋์ , persist() ๋ผ๋ ์ด๋ฆ์ ์ฌ์ฉํ๋ค. ๊ตณ์ด ํท๊ฐ๋ฆฌ๊ฒ ์ ์ด๋ ๊ฒ ๋ง๋ค์์๊น?
@ EntityManager.persist( ~ )
์ฌ์ค save ๋์ persist ๋ผ๋ ์ด๋ฆ์ ์ฌ์ฉํ ์ด์ ๋ ๊ฐ๋จํ๋ค.
์ค์ ๋์์ด ๊ฐ์ฒด๋ฅผ DB์ ์ ์ฅํ๋๊ฒ ์๋๋ผ, ์์์ฑ ์ปจํ ์คํธ์ ์ ์ฅ(=persist)ํ๊ธฐ ๋๋ฌธ์ด๋ค.
์ดํดํ๊ธฐ ์ฝ๊ฒ ์ฝ๋๋ฅผ ํตํด ์์๋ณด์.
try {
// ๊ฐ์ฒด๋ฅผ ์์ฑํ ์ํ(๋น์์)
Member member = new Member();
member.setId("member1");
member.setUsername("ํ์1");
// ๊ฐ์ฒด๋ฅผ ์ ์ฅํ ์ํ (์์)
entityManager.persist(member)
tx.commit();
} catch (Exception e) {
tx.rollback();
์ฝ๋๋ฅผ ๋ณด๋ฉด em.persist()๋ฅผ ์คํํ์ ๋, DB์ ์ ์ฅ๋๋ ๊ฒ์ฒ๋ผ ๋ณด์๋ค.
ํ์ง๋ง ์ค์ ๋ก ํ์ธํ๋ฉด em.persist()๋ ์์์ฑ ์ปจํ ์คํธ(EntityManager)์ ์์ ๋ฟ, ์์ง DB์ ์ ์ฅ๋๊ฒ ์๋๋ค.
@ ์์์ฑ ์ปจํ ์คํธ == EntityManager ์ธ ๊ฑด๊ฐ์?
์๋๋ค. ์ ํํ๋ EntityManager๊ฐ ์์์ฑ ์ปจํ ์คํธ๋ฅผ ์ฌ์ฉํ ์ ์๊ฒ ์ ๊ณตํด์ฃผ๋ ๊ฒ์ด๋ค.
์๋์ ๊ฐ์ด EntityManager์ ๊ฐ์ฒด๊ฐ ์กด์ฌํ์ง๋ง, ๋น์์ ์ํ(=์ค์์) ์ผ๋ก ๋ง๋ค ์๋ ์๋ค.
์ฐธ๊ณ ๋ก ์์ ์์๋ EntityManager๋น ๊ณ ์ ํ ์์์ฑ ์ปจํ ์คํธ๋ฅผ ๊ฐ์ง๊ณ ์์์ง๋ง, ์คํ๋ง ํ๋ ์์ํฌ๋ฑ์ ์ฌ์ฉํ ๋์๋ ์ฌ๋ฌ ๊ฐ์ EntityManager๊ฐ ํ๋์ ์์์ฑ ์ปจํ ์คํธ๋ฅผ ๊ณต์ ํด์ ์ฌ์ฉํ ์๋ ์๋ค.
์ด๋ ์์์ฑ ์ปจํ ์คํธ๋ฅผ ๊ณต์ ํ๋ค๊ธฐ ๋ณด๋ค๋,
ํ ํธ๋์ญ์ ์์์ ์ฌ๋ฌ ๋ชจ๋์ด ํธ์ถ๋๋ ์คํ ๊ตฌ์กฐ, ์๋ฅผ ๋ค์ด Application โก Service โก Repository ์ ๊ฐ์ ๊ฒฝ์ฐ EntityManager๋ฅผ ๊ณ์ ๊ณต์ ํ๋๊ฒ ์๋๋ผ ์๋ก์ด EntityManager๋ฅผ ๋ง๋ค์ด ์ฌ์ฉํ ์ ์๋๋ฐ, ์ด๋ฐ ๊ฒฝ์ฐ์๋ง ํ๋์ ์์์ฑ ์ปจํ ์คํธ๋ฅผ ๊ณต์ ํ๋ค๋ ๋ง์ด๋ค. ์ง๊ธ์ ์ดํดํ ํ์์์ผ๋ ์์๋ง๋๊ณ ๋์ด๊ฐ๋๋ก ํ์.
@ ๊ท์ฐฎ๊ฒ ์์์ฑ ์ปจํ ์คํธ๋ฅผ ๊ฑฐ์น๋ ์ด์ ๊ฐ ๋ญ์ฃ ?
DB์ ๋ฐ๋ก ์ ์กํ์ง์๊ณ , ์ค๊ฐ์ ๋ฒํผ์ฒ๋ผ ์์์ฑ ์ปจํ ์คํธ๋ฅผ ์ด์ฉํ๋ ์ด์ ๋ ์ฌ๋ฌ๊ฐ์ง๊ฐ ์๋ค.
- DB๋ฅผ ๊ฑฐ์น์ง ์๊ณ 1์ฐจ ์บ์์์ ๋ฐ๋ก ์ฌ์ฉ๊ฐ๋ฅ
- ๋์ผ์ฑ (identity) ๋ณด์ฅ
- ํธ๋์ญ์ ์ ์ง์ํ๋ ์ฐ๊ธฐ ์ง์ฐ (tx write-behind)
- ๋ณ๊ฒฝ ๊ฐ์ง๋ฅผ ํตํ ์ต์ ํ (Dirty Checking)
- ์ง์ฐ ๋ก๋ฉ ์ง์ (Lazy Loading)
๐ ์์์ฑ ์ปจํ ์คํธ์ ํน์ง
@ 1์ฐจ ์บ์ ์ ๊ณต
EntityManager๋ฅผ ์ด์ฉํ๋ฉด DB๋ฅผ ๊ฑฐ์น์ง ์๊ณ , ์ค๊ฐ์ ์บ์๋ ๋ฐ์ดํฐ๋ฅผ ๋ฐ๋ก ๊ฐ์ ธ์ฌ ์ ์๋ค.
๋ค๋ง ํ ํธ๋์ญ์ ์์์๋ง ์ฌ์ฉํ ์ ์๋ ์บ์(1์ฐจ)๋ผ์ ๋น์ฆ๋์ค ๋ก์ง์ด ์์ฒญ ๋ณต์กํ๊ฒ ์๋๋ผ๋ฉด, ๋ณ ์ฐจ์ด์๋ค.
๊ณ ๊ฐ์ด 10๋ช ์ด๋ฉด 10๊ฐ์ 1์ฐจ ์บ์๊ฐ ๋ง๋ค์ด์ง๋๊ฑฐ๋๊น. ๊ทธ๋ฅ ๊ตฌ์กฐ์ ์ป๋ ์์ํ ์ด๋์ด๋ผ๊ณ ์๊ฐํ๋ฉด ๋๋ค.
์ฆ ์์ ๊ฐ์ ๊ฒฝ์ฐ, DB์ Select ์ฟผ๋ฆฌ๊ฐ ๋ ๋ผ๊ฐ์ง ์๋๋ค. ๋ง ๊ทธ๋๋ก DB๋ฅผ ์ฌ์ฉํ ์ ์ด ์์ผ๋๊น.
@ ์์๋ ์ํฐํฐ์ ๋์ผ์ฑ ๋ณด์ฅ
JPA์ ๊ฐ์ฅ ํฐ ์ฅ์ ์ค ํ๋์ด๋ค.
์์์ฑ ์ปจํ ์คํธ์์ ๊ฐ์ฒด๋ฅผ ๊ด๋ฆฌํ๊ธฐ ๋๋ฌธ์, ๊ฐ์ฒด๋ฅผ ์ฌ๋ฌ๋ฒ ์กฐํํ๋๋ผ๋ ๋์ผ์ฑ์ ๋ณด์ฅํ๋ค.
์ด๋ ์ ๋ง ํฐ ์ฐจ์ด์ธ๊ฒ, ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ํธ๋์ญ์ ๊ฒฉ๋ฆฌ ๋ ๋ฒจ์ 3. REPEATABLE READ๋ก ํ ํ์๊ฐ ์์ด์ง๋ค.
์ฑ (Java)๋จ์์ [ํ ํธ๋์ญ์ ๋ด์ ๊ฐ์ ๋ฐ์ดํฐ๋ฅผ ๋ช ๋ฒ์ ๋ฐ๋ณตํด์ ์ฝ์ด๋] ๋์ผ์ฑ์ ๋ณด์ฅํ๊ธฐ ๋๋ฌธ์ด๋ค.
@ ํธ๋์ญ์ ์ ์ง์ํ๋ ์ฐ๊ธฐ ์ง์ฐ ์ ๊ณต
ํ ํธ๋์ญ์ ๋ด์์, em.persist()๋ฅผ ์ฌ์ฉํ๋ค ํ๋๋ผ๋ ๋ฐ๋ก DB์ ์ ์ฅ๋์ง ์๊ฒ ์ฐ๊ธฐ ์ง์ฐ์ ์ ๊ณต ํด์ค๋ค.
์ด๋ EntityManager (์์์ฑ ์ปจํ ์คํธ)์์ ์บ์์ ํจ๊ป ์ฐ๊ธฐ์ง์ฐ SQL ์ ์ฅ์๋ฅผ ๊ฐ์ง๊ณ ์๊ธฐ ๋๋ฌธ์ด๋ค.
์ฐธ๊ณ ๋ก JPA๋ JDBC Batch๋ฅผ ์ด์ฉํ์ฌ ์ฐ๊ธฐ ์ง์ฐ์ ๊ตฌํํ์๋ค. (hibernate.jdbc.batch_size ์ต์ ์ค์ ๊ฐ๋ฅ)
JPA๋ฅผ ์ฌ์ฉํ๋ฉด commitํ๋ ์์ ์ ๋ณ๊ฒฝ๋ ๋ถ๋ถ์ ๊ฐ์งํ์ฌ SQL ์ฟผ๋ฆฌ๋ฅผ ์์ฑํ๊ธฐ ๋๋ฌธ์ด๋ค.
์์๋ ์ธ๊ธํ์ง๋ง, ๋ฐ๋ก ์ ์ฅํ์ง ์๊ณ [์ฐ๊ธฐ ์ง์ฐ SQL ์ ์ฅ์]์ ์ฟผ๋ฆฌ๋ฅผ ์์๋๋ค๊ฐ ํธ๋์ญ์ ์ด ์ปค๋ฐํ๋ ์์ (commit)์ ๋ณ๊ฒฝ๋ ๋ถ๋ถ๋ง ๊ฐ์งํ์ฌ, ์ต์ ํ๋ SQL๋ฌธ์ ์์ฑํ๊ฒ ๋๋ค.
์ด๋ฐ ๋ถ๋ถ ๋๋ฌธ์, ์๋ง ์ฌ์ฉํ๋ค๋ฉด JDBC๋ฅผ ๋ฐ๋ก ์์ฑํ๋ ๊ฒ ๋ณด๋ค JPA๋ฅผ ๊ฑฐ์น๋๊ฒ ์ฑ๋ฅ์ด ๋ ์ข์ ์ ์๋ค๋ ๋ง์ด ๋์จ ๊ฒ์ด๋ค.
@ ๋ณ๊ฒฝ ๊ฐ์ง (Dirty Checking)
์ด๋ ์ฐ๊ธฐ ์ง์ฐ๊ณผ ๋น์ทํ ๋งฅ๋ฝ์ด๋ค. JPA๋ Entity์ ์ค๋ ์ท์ ์ฐ์ด๋๋ค๊ฐ, ์ปค๋ฐ๋๋ ์์ ์ ๋ณ๊ฒฝ๋ ๋ถ๋ถ์ ์ฐพ์ ์ต์ ํ๋ SQL์ ์์ฑํด๋ธ๋ค.
try {
// ์
๋ฐ์ดํธ๋ 2์ค์ด๋ฉด ๋.
Member member = entityManager.find(Member.class, 1L);
member.setName("new Name");
// ์ ์ฅํ ํ์๊ฐ ์๋ค. ๋ณ๊ฒฝ๋๋ฉด ์์์ ์ฟผ๋ฆฌ๊ฐ ์์ฑ๋๋ค.
// ์ด๋ ์ค์ ์ปฌ๋ ์
๋ ๊ทธ๋ ๋ค. ์ฐ๋ฆฌ๊ฐ ์ปฌ๋ ์
์ ๋ณ๊ฒฝํ๊ณ , ๋ฐ๋ก ์ ์ฅ ๋ฉ์๋๋ฅผ ํธ์ถํ์ ์ด ์๋๊ฐ?
tx.commit();
} catch (Exception e) { ... }
์ฐธ๊ณ ๋ก flush() ๋ ๋ณ๊ฒฝ ๋ด์ฉ์ ๋ฐ์ํ๋ ๋ฉ์๋์ด๋ค. ๋ง์ฝ ํธ์ถ๋๋ค๋ฉด [์ฐ๊ธฐ ์ง์ฐ ์ ์ฅ์์ ์๋ ์ฟผ๋ฆฌ]๋ฅผ DB์ ์ ์กํ๋ค.
์ฝ๊ฒ๋งํด ํ๋ฌ์๋ฅผ ํ๋ ์์ ์ DB ์ฟผ๋ฆฌ๊ฐ ๋ฐ์ํ๋ค. ๋ฌผ๋ก ์ปค๋ฐํ๊ธฐ ์ ๊น์ง ์ค์ ํ ์ด๋ธ์ ๋ฐ์์ ๋์ง ์๊ฒ ์ง๋ง.
ํธ๋์ญ์ ์ด ์ปค๋ฐ๋๊ฑฐ๋ JPQL ์ฟผ๋ฆฌ๊ฐ ์คํ๋๋ฉด EntityManager.flush()๊ฐ ์๋์ผ๋ก ์คํ๋๋ค.
๋ฌผ๋ก EntityManager.flush()๋ก ์ง์ ํธ์ถํ๋ ๋ฐฉ๋ฒ๋ ์์ง๋ง, ์ฐ๋ฆฌ๊ฐ ์ฌ์ฉํ ์ผ์ ๊ฑฐ์ ์๋ค.
JPQL์ ๊ฒฝ์ฐ์๋, ์ฌ๋ฌ ๋ฐ์ดํฐ๋ฅผ ์กฐํํ๋ ๋ณต์กํ ์ฟผ๋ฆฌ๋ฅผ ์์๋ก ์บ์ฑํด์ ์ฐ๊ธฐ์ง์ฐ์ ๋ง๋ค์ด๋ฒ๋ฆฌ๋ฉด ๋ฌธ์ ๊ฐ ์๊ธฐ๊ธฐ ์ฝ๋ค. ๊ธฐ๋ณธ์ ์ผ๋ก JPQL์ ์คํํ๋ ์์ ์ ํ๋ฌ์, ์ฆ DB์กฐํ๊ฐ ์ผ์ด๋๋๋ก ์ค์ ๋์ด์๋ค.
์ฐธ๊ณ ๋ก ์๋ ํ๋ฌ์๋ ์ต์ ์ผ๋ก ์ค์ ์ ๋ฐ๊ฟ ์ ์๋ค. ๋ฌผ๋ก ์ฌ์ฉํ ์ผ์ ์๋ค.
ํท๊ฐ๋ฆด๊น๋ด ์ธ๊ธํ์ง๋ง, ํ๋ฌ์๋ ์์์ฑ ์ปจํ ์คํธ๋ฅผ ์ญ์ ํ๊ฑฐ๋ ๋น์ฐ๋๊ฒ ์๋๋ค.
๊ทธ๋ฅ ์์์ฑ ์ปจํ ์คํธ๊ฐ ๊ฐ์ง๊ณ ์๋ (์ฐ๊ธฐ ์ง์ฐ๋) ๋ณ๊ฒฝ ๋ด์ฉ์ DB์ ๋๊ธฐํ ํ๋ ๊ฒ ๋ฟ์ด๋ค.
๋๊ธฐํ๋ฅผ ๋ฆ๊ฒ ํด๋ ๋๋ ์ด์ ๋ ํธ๋์ญ์ Commit ์ง์ ์๋ง ๋๊ธฐํ๋ฅผ ํด์ฃผ๋ฉด ๋ฌธ์ ๊ฐ ์๊ธฐ ๋๋ฌธ์ด๋ค.
@ ์ค์์ ์ํ
EntityManager์๋ ์กด์ฌํ์ง๋ง, ์์ํ ํ์ง ์๋ ๊ฐ์ฒด๋ฅผ ์๋ฏธํ๋ค. ์ต๊ทผ์๋ `์ค์์` ๋์ `์์์ํ ๋ถ๋ฆฌ` ๋ผ๊ณ ๋ ๋ถ๋ฅธ๋ค. ๊ทธ๋์ ๋ฉ์๋ ๋ช ๋ detached() ์ฆ ์์์ฑ ์ปจํ ์คํธ์์ ์ ๊ณตํ๋ ๋ณ๊ฒฝ๊ฐ์ง, ์ฐ๊ธฐ ์ง์ฐ๋ฑ์ ์ฌ์ฉํ์ง ๋ชปํ๋ค.
๊ทผ๋ฐ JPA์์ ๊ฐ์ฒด๋ฅผ ๊ด๋ฆฌํ์ง ์๋๊ฑฐ๋ฉด ๊ทธ๋ฅ ๋น์์ ์ํ, ์ฆ JPA๋ฅผ ์๊ฑฐ์น๋ฉด ๋ ๊ฑฐ ๊ฐ์๋ฐ ์ ๊ตณ์ด ์ค์์ ์ํ๋ผ๋๊ฑธ ๋๊ณ EntityManager ์์์ ๊ฐ์ฒด๋ฅผ ์ฌ์ฉํ๋ ๊ฑธ๊น?
๊ทธ ์ด์ ๋ 'ํ๋ฒ ์์์ํ๊ฐ ๋์๋ค๊ฐ ์ทจ์๋ ๊ฒฝ์ฐ์๋ ๊ฐ์ฒด์ ์๋ณ์๊ฐ ๋จ์์๊ธฐ ๋๋ฌธ' ์ด๋ค.
์ด๋ ํ์์๋ ๊ฑฐ์ ์ธ ์ผ์ด์๊ณ ๋ณต์กํ ๋น์ฆ๋์ค ์๋น์ค๋ฅผ ๋ง๋ค๋ ์ข ์ข ์ฐ์ด๋๋ฐ, ์ด๋ JPA์ ์ด๋์ ๋ ์ต์ํด ์ง ๋ค์์ ์ฒ์ฒํ ์์๋ณด๋๋ก ํ์.
'๐ฑBackend > JDBC & JPA' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
JPA #6 ๋ค์ํ ์ฐ๊ด๊ด๊ณ ๋งคํ (1:N, N:1, N:N) (0) | 2021.11.09 |
---|---|
JPA #5 ๋ฐ์ดํฐ ์ค์ฌ ์ค๊ณ์ ๋ฌธ์ ์ , ์ฐ๊ด ๊ด๊ณ ๋งคํ (0) | 2021.11.09 |
JPA #4 ์ํฐํฐ ๋งคํ (๊ฐ์ฒด-ํ ์ด๋ธ ๋งคํ) (0) | 2021.11.08 |
JPA #2 ๋ณธ๊ฒฉ์ ์ผ๋ก ์์๋ณด์. (0) | 2021.11.07 |
JPA #1 ๊ฐ์ฒด๋ฅผ ๋ฐ์ดํฐ๋ก ์ ์ฅํ๋ ๋ฐฉ๋ฒ (0) | 2021.11.07 |
๋ธ๋ก๊ทธ์ ์ ๋ณด
JiwonDev
JiwonDev