[Spring] Persistence Context 알아보기

WOOK JONG KIM·2022년 11월 21일
0

패캠_java&Spring

목록 보기
58/103
post-thumbnail

Context: 스프링에서 컨테이너가 관리하고 있는 내용들을 일컬음

Persistence Context: Persistence 컨테이너가 관리하고 있는 내용

Persistence(영속화): 사라지지 않고 지속적으로 접근할 수 있는 것을 의미

메모리의 존재하는 데이터는 서비스가 종료되면 사라짐

파일, 데이터베이스에 저장하면 서비스에 상관 없이 사라지지않고 존재

EntityManager: 영속성 컨텍스트의 주체적인 역할

JPA를 사용하기 위해 META-INF > persistence.xml 을 통해 설정이 필요

스프링 부트는 build.gradle에 org.springframework.boot:spring-boot-starter-data-jpa 를 통해 Persistence Context에 설정을 처리

Dialect
데이터베이스 방언을 의미 → 각각의 DB마다 다른 부분을 맞춰주는 기능

JPA는 ORM을 통해 데이터베이스 쿼리로 변환을 해서 JDBC를 통해 전달 → 특정 데이터베이스에 쿼리로 자동으로 변경해 줄 때 사용 (varchar, varchar2 등)

Mysql로 Db 변경

build.gradle

dependencies {
		...
		runtimeOnly 'mysql:mysql-connector-java'
}

mysql에 DB 추가

create database book_manager;

application.yml

spring:
  h2:
    console:
      enabled: true
  jpa:
    show-sql: true
    properties:
      hibernate:
        format_sql : true
    generate-ddl: true
    hibernate:
      ddl-auto: create-drop
  datasource:
    url: jdbc:mysql://localhost:3306/book_manager
    username : root
    password : root
    initialization-mode: always
logging:
  level:
    #    org.hibernate.SQL: DEBUG
    org.hibernate.type: trace
server:
  port: 8070

spring.jpa.generate-ddl: H2(임베디드 DB)에선 자동 생성, Mysql(상용)에선 설정 필요

spring.jpa.hibernate.ddl-auto

  • none: ddl-auto 실행하지 않는 옵션
  • create: 항상 새로 생성하는 옵션 ( drop → create )
  • create-drop: 생성하고 종료될 때 자동으로 drop ( create → drop )
  • update: 실제 스키마와 엔티티를 비교해서 변경된 부분만 반영 ( drop X )
  • validate: 스키마와 엔티티를 비교만하고 다른 경우 오류 발생

-> 영속성 컨텍스트와 연관된 개념


ddl-auto , generate-ddl 옵션간 차이

테스트 환경

  • H2 데이터베이스를 사용할 시 자동으로 DDL 처리를 설정
    generate-ddl, ddl-auto 옵션을 사용할 필요가 없음

운영 환경

  • 자동화 된 ddl을 사용하는 경우 리스크가 발생
    generate-ddl: false, ddl-auto: none 으로 지정
    간혹 ddl-auto: validate 는 사용

generate-ddl - ddl-auto 옵션의 차이

  • generate-ddl
    jpa는 인터페이스 모음-> 구현체와 상관없이 자동화된 ddl을 사용하도록 하는 옵션
    범용적인 옵션

  • ddl-auto
    hibernate에 특화된 구체적인 옵션
    스프링: 임베디드 DB(H2)에선 default로 ddl-auto: create-drop
    스프링에 우선순위는 ddl-auto > generate-ddl
    ddl-auto 옵션이 존재하면 generate-ddl 옵션은 무시 → generate-ddl: false, ddl-auto: create-drop인 경우 ddl-auto 옵션으로 실행

initialization-mode: always
-> application.yml에 추가하는 옵션, 현업에선 none을 명시적으로 해주는 것이 좋음

운영 데이터베이스(Mysql, 등)가 실행될 때 초기 SQL(파일) 실행 여부(data.sql, schema.sql)

spring.sql.init.mode(schema.sql), ddl-auto(create-drop)옵션 충돌이 발생할 수 있음
스프링에 우선순위 옵션 spring.sql.init.mode > ddl-auto(무시됨)

data.sql은 단순히 넣는거지만 schema.sql은 스키마 자체를 생성해 주는 것

테스크 클래스 상단에 @Transactional을 선언
-> 각 테스트 메소드가 종료될 때 마다 Db Rollback


@WebMvc Test 오류 해결 방법

이후 다른 테스트들은 통과하지만 @WebMvcTest에서 오류가 발생함
-> Controller에 대한 일부의 Bean만 로드 하기 때문

1

@WebMvcTest
@MockBean(JpaMetamodelMappingContext.class)

2

@SpringBootApplication
@EnableJpaAuditing // 여기서 이것 제거 후 밑에 코드 추가
public class Bookmanager2Application {

    public static void main(String[] args) {
        SpringApplication.run(Bookmanager2Application.class, args);
    }

}

@EnableJpaAuditing 을 별도의 빈에서 로딩 시켜주는 방법

@Configuration
@EnableJpaAuditing 
public class JpaConfiguration{

}

3

@SpringBootTest
class HelloWorldControllerTest {

    @Autowired
    private WebApplicationContext wac;
    
    private MockMvc mockMvc;
    
    @BeforeEach
    void before() {
        mockMvc = MockMvcBuilders.webAppContextSetup(wac).build();
    }
    
    ...
}

webMvcTest에서 자동으로 만들어 주던 MockMvc를 직접 만들어 주는 방법

slice Test(WebMvc Test)사용하지않고 SpringBootTest를 사용하기에 모든 컨텍스트가 다 올라옴

2번째 방식이 제일 바람직 -> 따른 방법은 다른 개발자가 사용 시 오류를 유발할 가능성 높음

profile
Journey for Backend Developer

0개의 댓글