> ## Content Index
> Fetch the complete content index at: https://www.popit.kr/llms.txt
> Use this file to discover other available public pages before exploring further.

# 스프링 부트 2.0 JPA Auto-configuration의 변화
- URL: https://www.popit.kr/spring-boot-2-jpa-autoconfiguration-changes/
- Published: 2018-10-04T00:12:39.000Z
- Updated: 2018-10-05T00:00:21.000Z
- Author: 유 영모
- Tags: #소프트웨어, Spring Boot, Spring, JPA, Hibernate

스프링 애플리케이션을 만들 때 [스프링 프레임워크Spring Framework](https://spring.io/projects/spring-framework?ref=popit.kr#overview)로 직접 구성하기보다는 [스프링 부트Spring Boot](http://spring.io/projects/spring-boot?ref=popit.kr)를 사용하는 것이 더 간단하고 쉽다. 그리고 그 중심에는 스프링 부트 [자동 설정Auto-configuration](https://docs.spring.io/spring-boot/docs/current/reference/html/using-boot-auto-configuration.html?ref=popit.kr)이 있다. 스프링 부트 자동 설정은 스프링 애플리케이션에 추가한 라이브러리(JAR)를 인식하여 관련 값을 스프링 부트 기본으로 설정해 준다. 따라서 스프링 부트를 사용하는 입장에서는 자동으로 해주는 부분 이외에 필요한 설정만 하면 되니 편하다.

최근 [스프링 부트 2.0](https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-2.0-Release-Notes?ref=popit.kr)이 공개되었다. 많은 변화가 있지만 이 글에서는 변화된 [JPAJava Persistence API](https://en.wikipedia.org/wiki/Java%5FPersistence%5FAPI?ref=popit.kr) 자동 설정에 대해 다룬다.

# [StackOverFlow](https://stackoverflow.com/?ref=popit.kr)를 보다가

StackOverFlow는 [스택 익스체인지](https://en.wikipedia.org/wiki/Stack%5FExchange?ref=popit.kr) 네트워크의 대표 사이트로 컴퓨터 프로그래밍에 관련된 폭넓은 주제로 질문과 답을 하는 곳이다.\[1\]

StackOverFlow에서 필자는 '[Has Spring-boot changed the way auto-increment of ids works through @GeneratedValue?](https://stackoverflow.com/questions/49241216/has-spring-boot-changed-the-way-auto-increment-of-ids-works-through-generatedva?ref=popit.kr)'라는 제목의 질문을 보았는데 질문의 요지는 스프링 부트에서 JPA [**@GeneratedValue**](https://docs.oracle.com/javaee/6/api/javax/persistence/GeneratedValue.html?ref=popit.kr)**가 스프링 부트 1.5와 2.0이 다르게 동작하는 이유**가 무엇이냐는 것이었다.

![갈무리. https://stackoverflow.com/questions/49241216/has-spring-boot-changed-the-way-auto-increment-of-ids-works-through-generatedva](https://www.popit.kr/content/images/wp/2018/10/image2018-9-12_8-39-35.png)

갈무리. https://stackoverflow.com/questions/49241216/has-spring-boot-changed-the-way-auto-increment-of-ids-works-through-generatedva

# JPA GeneratedValue 어노테이션

GeneratedValue는 데이터베이스 테이블 주키Primary Key를 자동 생성하는 기능이다. 자동 생성 전략을 4개로 지정해 줄 수 있는데 지정해 주지 않으면 기본값은 'AUTO'이다.

| 생성 전략         | 설명                                                                     |
| ------------- | ---------------------------------------------------------------------- |
| AUTO(default) | JPA 구현체가 자동으로 생성 전략을 결정한다.                                             |
| IDENTITY      | 기본키 생성을 데이터베이스에 위임한다. 예를 들어 MySQL의 경우 AUTO\_INCREMENT를 사용하여 기본키를 생성한다. |
| SEQUENCE      | 데이터베이스의 특별한 오브젝트 시퀀스를 사용하여 기본키를 생성한다.                                  |
| TABLE         | 데이터베이스에 키 생성 전용 테이블을 하나 만들고 이를 사용하여 기본키를 생성한다.                         |

출처 : [자바 ORM 표준 JPA 프로그래밍](http://www.yes24.com/24/goods/19040233?scode=032&OzSrank=3&ref=popit.kr) 4.6 기본키 매핑

더 자세한 내용은 필자의 [이전 글 '하이버네이트는 어떻게 자동 키 생성 전략을 결정하는가'](https://www.popit.kr/how-hibernate-decides-key-generation-strategy/)에 나와 있다.

# 문제 확인

StackOverFlow 질문자의 코드를 MySQL로 스프링 부트 1.5와 2.0으로 테스트해 보았다. 질문자의 코드는 GeneratedValue 어노테이션에 자동 생성 전략을 지정해 주지 않았기 때문에 'AUTO'이며 이것은 곧 JPA 구현체(하이버네이트)가 자동으로 결정하라는 의미이다.  

```java
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
 
@Entity
public class Airplane {
  @Id
  @GeneratedValue
  private Long id;
  private String name;
  //...
}
 
@Entity
public class Car {
  @Id
  @GeneratedValue
  private Long id;
  private String name;
  //...
}
```

하이버네이트의 스키마 자동 생성 기능\[2\]을 사용하여 생성된 스키마를 확인해 보았더니 결과는 아래와 같았다.

| 스프링 부트 1.5                                                                                           | 스프링 부트 2.0                                                                                         |
| ---------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------- |
| ![image2018-10-1_10-0-20](https://www.popit.kr/content/images/wp/2018/10/image2018-10-1_10-0-20.png) | ![image2018-10-1_10-1-4](https://www.popit.kr/content/images/wp/2018/10/image2018-10-1_10-1-4.png) |

표. 스프링 부트 하이버네이트 로그

같은 코드임에도 불구하고 **스프링 부트 1.5에서는 MySQL의 auto\_increment**를 사용하는데 반해 **2.0에서는 hibernate\_sequence 테이블을 추가로 생성**하고 이를 사용하여 INSERT 시 id 값을 채우고 있다.

# 왜 다르게 동작하는가

우선 스프링 부트에서 사용하고 있는 하이버네이트 버전이 다르다. 1.5는 하이버네이트 5.0을 사용하고 2.0은 하이버네이트 5.2를 사용한다. 하이버네이트 버전이 달라져서 그런 것일까?

**결론부터 말하자면 하이버네이트 버전하고는 상관없다. 스프링 부트 2.0에서 JPA 자동 설정 코드를 변경했다.** GeneratedValue(AUTO)를 사용하는 경우 하이버네이트는 여러 가지를 고려하여 키 생성 전략을 자동으로 판단하는데\[3\] 스프링 부트의 하이버네이트 자동 설정이 1.5에서 2.0으로 버전이 올라가면서 변경되었고 이 영향으로 하이버네이트 키 생성 전략이 달라진 것이다.

# 스프링 부트 JPA Auto-configuration

앞서 필자는 스프링 부트 JPA 자동 설정 과정에서 하이버네이트 '키 생성 전략 결정에 영향을 주는 값'을 설정해 주는 코드가 2.0에서 변경되었다고 언급했다. 그 값은 바로 '[hibernate.id.new\_generator\_mappings](https://docs.jboss.org/hibernate/orm/5.2/userguide/html%5Fsingle/Hibernate%5FUser%5FGuide.html?ref=popit.kr#%5Fidentifier%5Foptions)' 이다. **스프링 부트는 하이버네이트 'hibernate.id.new\_generator\_mappings' 프로퍼티 기본 값을 1.5 버전에서는 'FALSE'로 2.0 버전에서는 'TRUE'로 설정한다.**

![갈무리. 스프링 부트 1.5 코드 'hibernate.id.new_generator_mappings' 프로퍼티를 FALSE로 설정](https://www.popit.kr/content/images/wp/2018/10/image2018-9-5_10-58-0-1024x874.png)

갈무리. 스프링 부트 1.5 코드 'hibernate.id.new\_generator\_mappings' 프로퍼티를 FALSE로 설정

![갈무리. 스프링 부트 2.0 코드 'hibernate.id.new_generator_mappings' 프로퍼티를 TRUE로 설정](https://www.popit.kr/content/images/wp/2018/10/image2018-9-5_11-5-36-1024x922.png)

갈무리. 스프링 부트 2.0 코드 'hibernate.id.new\_generator\_mappings' 프로퍼티를 TRUE로 설정

하이버네이트는 'hibernate.id.new\_generator\_mappings' 프로퍼티 값에 따라 자동 생성 전략을 결정한다.

![그림. 하이버네이트 Interpreting AUTO](https://www.popit.kr/content/images/wp/2018/10/image2018-9-28_8-49-42.png)

그림. 하이버네이트 Interpreting AUTO

# 정리

**스프링 부트 1.5는 hibernate.id.new\_generator\_mappings 가 'FALSE'이기 때문에 하이버네이트 자동 키 생성 전략이 Native Generator가 되어 방언(**[**MySQL5Dialect**](https://docs.jboss.org/hibernate/orm/5.2/javadocs/org/hibernate/dialect/MySQL5Dialect.html?ref=popit.kr)**)에 따라 'auto\_increment'가 된 것이며, 스프링 부트 2.0에서는 'TRUE' 이기 때문에 SequenceStyleGenerator를 사용하게 되고 MySQL이 Sequence를 지원하지 않기 때문에 Table Generator가 된 것이다.**

만약 스프링 부트 2.0에서 1.5와 동일하게 사용하고자 한다면 application.properties에 아래와 같이 추가한다.  

```
spring.jpa.properties.hibernate.id.new_generator_mappings = false
```

# 덧붙여

스프링 부트 1.4 릴리즈 노트에 이와 관련된 내용을 찾을 수 있다.

![갈무리. 스프링 부트 1.4 릴리즈 노트](https://www.popit.kr/content/images/wp/2018/10/%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7-2018-09-11-%EC%98%A4%EC%A0%84-10.38.35.png)

갈무리. 스프링 부트 1.4 릴리즈 노트

또한 스프링 부트 GitHub에도 역시 스프링 부트 2.0에서 이 값이 변경된 이력을 찾을 수 있다.

![갈무리. https://github.com/spring-projects/spring-boot/issues/7612](https://www.popit.kr/content/images/wp/2018/10/image2018-9-18_9-49-34-1024x579.png)

갈무리. https://github.com/spring-projects/spring-boot/issues/7612

# 주석

\[1\] [https://en.wikipedia.org/wiki/Stack\_Overflow](https://en.wikipedia.org/wiki/Stack%5FOverflow?ref=popit.kr)

\[2\] [https://docs.jboss.org/hibernate/orm/5.2/userguide/html\_single/Hibernate\_User\_Guide.html#configurations-hbmddl](https://docs.jboss.org/hibernate/orm/5.2/userguide/html%5Fsingle/Hibernate%5FUser%5FGuide.html?ref=popit.kr#configurations-hbmddl)

스프링 부트에서는 아래와 같이 설정한다.  

```
spring.jpa.hibernate.ddl-auto=create-drop
spring.jpa.properties.hibernate.show_sql=true
spring.jpa.properties.hibernate.use_sql_comments=true
spring.jpa.properties.hibernate.format_sql=true
```

\[3\] 상세한 내용은 '[하이버네이트는 어떻게 자동 키 생성 전략을 결정하는가](https://www.popit.kr/how-hibernate-decides-key-generation-strategy/)' 글 '하이버네이트 Interpreting AUTO'절 참조