์Šคํ”„๋ง ํ”„๋ ˆ์ž„์›Œํฌ์—์„œ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ๊ด€๋ จ ํ…Œ์ŠคํŠธ๋ฅผ ์ง„ํ–‰ํ•  ๋•Œ, ๊ฐ„ํ˜น org.hibernate.exception.SQLGrammarException ์˜ค๋ฅ˜๊ฐ€ ๋‚˜์™€์„œ ๋‹นํ™ฉํ•  ์ˆ˜ ์žˆ๋‹ค.

๊ทธ๋ฆฌ๊ณ  ํ•ด๋‹น ๋‚ด์šฉ์— ๋Œ€ํ•œ ํ•ด๊ฒฐ๊ณผ์ •์ด ๋ธ”๋กœ๊ทธ๋“ค์— ์ œ๋Œ€๋กœ ๋‚˜์™€์žˆ์ง€ ์•Š์•„ ๋งŽ์ด ๊ณ ์ƒ์„ ํ–ˆ๋‹ค..

๊ทธ ๋ฐฐ๊ฒฝ ๋‚ด์šฉ์— ๋Œ€ํ•ด

 

๊ฐ™์ด ๊ณต๋ถ€ํ•ด๋ฉด์„œ ์˜ค๋ฅ˜์— ๋Œ€ํ•ด ํŒŒ์•…ํ•ด๋ณด์ž!


 

์ด ์˜ค๋ฅ˜๋Š” ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ํ•„์š”ํ•œ ์‹œํ€€์Šค๋‚˜ ํ…Œ์ด๋ธ”์ด ์กด์žฌํ•˜์ง€ ์•Š์„ ๋•Œ ์ฃผ๋กœ ๋ฐœ์ƒํ•˜๋Š”๋ฐ
ํŠนํžˆ, @DataJpaTest๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ JPA ๊ตฌ์„ฑ ์š”์†Œ๋ฅผ ํ…Œ์ŠคํŠธํ•˜๋Š” ๊ฒฝ์šฐ,
ํ…Œ์ŠคํŠธ ํ™˜๊ฒฝ ์„ค์ •์ด ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ์ด๋ฃจ์–ด์ง€์ง€ ์•Š์•˜์„ ๋•Œ ์ด๋Ÿฌํ•œ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค.

์šฐ์„  @DataJpaTest ์—๋Œ€ํ•ด ์•Œ์•„๋ณด๋„๋ก ํ•ด๋ณด์ž.

DataJpaTest๋ž€?

@DataJpaTest๋Š” Spring Boot์—์„œ JPA ๊ด€๋ จ ๊ตฌ์„ฑ ์š”์†Œ๋ฅผ ํ…Œ์ŠคํŠธํ•  ๋•Œ ์‚ฌ์šฉํ•˜๋Š” ์ฃผ์š” ์–ด๋…ธํ…Œ์ด์…˜์ž…๋‹ˆ๋‹ค. ์ด ์–ด๋…ธํ…Œ์ด์…˜์€ ํ…Œ์ŠคํŠธ ์ค‘์ธ JPA ๊ตฌ์„ฑ ์š”์†Œ๋งŒ์„ ๋กœ๋“œํ•˜๋ฉฐ, ์ž„๋ฒ ๋””๋“œ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋ฅผ ์‚ฌ์šฉํ•ด ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์™€ ๋…๋ฆฝ์ ์ธ ํ…Œ์ŠคํŠธ๋ฅผ ๊ฐ€๋Šฅํ•˜๊ฒŒ ํ•œ๋‹ค.

๋ฐœ์ƒ ๊ฐ€๋Šฅํ•œ ์˜ค๋ฅ˜ ์‹œ๋‚˜๋ฆฌ์˜ค

  1. ์‹œํ€€์Šค ๋ˆ„๋ฝ ์˜ค๋ฅ˜:์ด ์˜ค๋ฅ˜๋Š” @GeneratedValue ์–ด๋…ธํ…Œ์ด์…˜์œผ๋กœ ID๋ฅผ ๊ด€๋ฆฌํ•  ๋•Œ ํ•„์š”ํ•œ ์‹œํ€€์Šค๊ฐ€ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ์ƒ์„ฑ๋˜์–ด ์žˆ์ง€ ์•Š์„ ๊ฒฝ์šฐ ๋ฐœ์ƒํ•œ๋‹ค. 
    org.hibernate.exception.SQLGrammarException: could not prepare statement [Sequence "FRANCHISE_SEQ" not found; SQL statement: select next value for franchise_seq [90036-214]] [select next value for franchise_seq]
  2. ํ…Œ์ด๋ธ” ๋ˆ„๋ฝ ์˜ค๋ฅ˜:์ด ์˜ค๋ฅ˜๋Š” ํ…Œ์ŠคํŠธ ์ค‘ ํ•„์š”ํ•œ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ํ…Œ์ด๋ธ”์ด ์กด์žฌํ•˜์ง€ ์•Š์„ ๋•Œ ๋‚˜ํƒ€๋‚œ๋‹ค.
    org.hibernate.exception.SQLGrammarException: could not prepare statement [Table "FRANCHISE" not found (this database is empty); SQL statement: /* insert for enha.eodilo.domain.Franchise *]

์‹œํ€€์Šค ๋ˆ„๋ฝ ์˜ค๋ฅ˜ ํ™”๋ฉด
ํ…Œ์ด๋ธ” ๋ˆ„๋ฝ ์˜ค๋ฅ˜ ํ™”๋ฉด

๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์ „๋žต์— ๋”ฐ๋ฅธ ๋‹ค๋ฅธ ์˜ค๋ฅ˜ ๋ฐœ์ƒ

H2 ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ, @GeneratedValue์— ๋ณ„๋„์˜ ์ „๋žต(strategy)์„ ์ง€์ •ํ•˜์ง€ ์•Š์œผ๋ฉด ๊ธฐ๋ณธ๊ฐ’์œผ๋กœ ์‹œํ€€์Šค๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.

๋งŒ์•ฝ ์ „๋žต์„ IDENTITY๋กœ ์„ค์ •ํ•˜๊ฑฐ๋‚˜, MySQL ๊ฐ™์€ ๋‹ค๋ฅธ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์˜ ๊ธฐ๋ณธ ์ „๋žต์„ ์‚ฌ์šฉํ•  ๊ฒฝ์šฐ, ํ…Œ์ด๋ธ”์ด ์กด์žฌํ•˜์ง€ ์•Š์•„ Table not found ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋‹ค.

์ด๋Ÿฌํ•œ ๋ฌธ์ œ๋Š” ํ…Œ์ŠคํŠธ ์‹œ JPA๊ฐ€ ์ž๋™์œผ๋กœ ํ…Œ์ด๋ธ”์„ ์ƒ์„ฑํ•˜์ง€ ์•Š์„ ๋•Œ ๋ฐœ์ƒํ•˜๋ฉฐ, ํŠนํžˆ ddl-auto๊ฐ€ none์ด๋‚˜ validate๋กœ ์„ค์ •๋œ ๊ฒฝ์šฐ ๋ฐœ์ƒํ•˜๊ฒŒ ๋œ๋‹ค.

ํ•ด๋‹น๋‚ด์šฉ์€ ์•„๋ž˜ ํฌ์ŠคํŒ… ์ฐธ์กฐ

https://jakezo.tistory.com/44

์ฆ‰, @GeneratedValue ์‚ฌ์šฉ์‹œ

strategy ๊ฐ€ SEQUENCE ๋ฉด 1๋ฒˆ์ธ ์‹œํ€€์Šค ๋ˆ„๋ฝ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•˜๊ณ 
strategy ๊ฐ€ IDENTITY ๋ฉด 2๋ฒˆ์ธ ํ…Œ์ด๋ธ” ๋ˆ„๋ฝ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค๋Š” ๋œป,

์ „๋žต์„ค์ •(h2๋Š” ๊ธฐ๋ณธ๊ฐ’์ด sequence๋‹ค)

์ด์ œ ํ•ด๋‹น ์˜ค๋ฅ˜์— ๋Œ€ํ•ด ํ•ด๊ฒฐ๋ฒ•์„ ์•Œ์•„๋ณด๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

1. SQL ์Šคํฌ๋ฆฝํŠธ, Flyway, Liquibase ๋“ฑ์„ ์‚ฌ์šฉํ•˜์—ฌ ํ…Œ์ŠคํŠธ ์‹คํ–‰ ์ „์— ์Šคํ‚ค๋งˆ๋ฅผ ์ค€๋น„

SQL ์Šคํฌ๋ฆฝํŠธ ์‚ฌ์šฉํ•˜๊ธฐ ์˜ˆ์‹œ

์ €์˜ ๊ฒฝ์šฐ์—๋Š” SQL ์Šคํฌ๋ฆฝํŠธ๋กœ ์˜ˆ์‹œ๋ฅผ ๋งŒ๋“ค์–ด ๋ณด์•˜์Šต๋‹ˆ๋‹ค.
Spring Boot ํ”„๋กœ์ ํŠธ์—์„œ๋Š” src/main/resources ๋””๋ ‰ํ† ๋ฆฌ ์•„๋ž˜์— schema.sql ํŒŒ์ผ์„ ๋‘๊ณ  ์ด ํŒŒ์ผ์— ํ…Œ์ด๋ธ” ์ƒ์„ฑ ์ฟผ๋ฆฌ๋ฅผ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํ…Œ์ŠคํŠธ ํ™˜๊ฒฝ์—์„œ๋Š” src/test/resources์— schema.sql์„ ๋‘์–ด ํ…Œ์ŠคํŠธ ์ „์šฉ ์Šคํ‚ค๋งˆ๋ฅผ ์„ค์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.์˜ˆ๋ฅผ ๋“ค์–ด, ๋‹ค์Œ๊ณผ ๊ฐ™์€ schema.sql์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

CREATE TABLE franchise ( 
franchise_id BIGINT AUTO_INCREMENT PRIMARY KEY, 
admin_id BIGINT, 
name VARCHAR(255), 
kind VARCHAR(255),
...
);

DROP SEQUENCE IF EXISTS franchise_SEQ;  
CREATE SEQUENCE franchise_SEQ INCREMENT BY 50;

2. @DataJpaTest์— properties ์„ค์ • ์ถ”๊ฐ€

ํ…Œ์ŠคํŠธ ์–ด๋…ธํ…Œ์ด์…˜์— ์ง์ ‘ ํ”„๋กœํผํ‹ฐ๋ฅผ ์ถ”๊ฐ€ํ•˜์—ฌ, ํ…Œ์ŠคํŠธ ์ค‘ ID ์ƒ์„ฑ ์ „๋žต ๋“ฑ์„ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

@DataJpaTest(properties = { "spring.jpa.hibernate.ddl-auto=update"})

3. ํ…Œ์ŠคํŠธ ์ „์šฉ application.yml ์„ค์ •

spring:
    jpa:  
      hibernate:  
        ddl-auto: update

ddl-auto ๋ฅผ none์ด๋‚˜ validate ๊ฐ€ ์•„๋‹Œ ๊ฐ’์œผ๋กœ ๋ณ€๊ฒฝํ•œ๋‹ค.

์ด ๋ฐฉ๋ฒ•๋“ค์„ ํ†ตํ•ด, ํ…Œ์ŠคํŠธ ํ™˜๊ฒฝ์—์„œ @GeneratedValue ์–ด๋…ธํ…Œ์ด์…˜์ด ์ ์šฉ๋œ ์—”ํ‹ฐํ‹ฐ์˜ ID๊ฐ€ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ๊ด€๋ฆฌ๋˜๋ฉฐ, ํ•„์š”ํ•œ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ํ…Œ์ด๋ธ”๊ณผ ์‹œํ€€์Šค๊ฐ€ ์กด์žฌํ•˜์ง€ ์•Š๋Š” ๋ฌธ์ œ๋ฅผ ์‚ฌ์ „์— ๋ฐฉ์ง€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.