---
tags: jpa, error, mysql, MySQL5InnoDBDialect
---
JPA erorr - Specified key was too long; max key length is 1000 bytes
===
Entity에 적힌 필드들로 테이블을 create 후, 이후에 alter로 unique 를 잡아줄때 다음과 같은 에러가 발생했다.
```
alter table account
add constraint UK_gex1lmaqpg0ir5g1f5eftyaa1 unique (username)" via JDBC Statement
org.hibernate.tool.schema.spi.CommandAcceptanceException: Error executing DDL "
중략...
Caused by: java.sql.SQLSyntaxErrorException: Specified key was too long; max key length is 1000 bytes
```
> 대략 uk 키의 최대 크기는 1000바이트 라는 뜻이다.
JPA에서 `spring.jpa.hibernate.ddl-auto=create` 옵션으로 자동으로 테이블을 생성할때 MyISAM 캐릭터셋이 utf8mb4 만들더라.
utf8 이면 1글자당 3바이트 인 반면, utf8mb4는 **4바이트 이다.**
따라서 기본으로 생성해주는 varchar(255) 는 255*4 가 1020 을 잡게되어 1000바이트를 초과하면서 위와 같은 에러가 발생한 것이다.
몇가지 해결방법을 찾아봤는데 다음과 같다.
## 해결방법
아래의 셋중 하나만 해결되어도 에러를 잡을수 있다.
1. `length = 250` 을 설정해서 1000 바이트 이하로 생성 되게 한다
2. 테이블 캐릭터셋을 utf8로 바꾼다
3. **테이블 엔진을 MyISAM -> InnoDB로 바꾼다**
사실상 1,2번은 적절치 못하다. 심지어 3번은 InnoDB 자체가 대세라 당연하게 설정을 하게 될 것이다.
결론적으로 3번만 봐도 해결이 되겠지만, 학습을 위해 각 해결방법을 통해 원리를 이해해 보자.
### 1. length = 250
요즘 mysql 기본 생성되는 캐릭터셋은 4바이트를 차지하는 utf8mb4 로 만들어 진다.
> 내가 처음에 디비 입문할땐 utf8 이었고 100년 200년은 쓸수있는 캐릭터셋이라고 어디서 들었던것 같은데.. 참 빠르다.
덕분에 4바이트인 이모지를 표현할 수가 있다.
다만 문제는 JPA가 테이블 생성시 String 값에 length 를 안넣으면 VARCHAR(255) 로 생성을 하는데 255 * 4 가 1000바이트를 넘게되어 발생한 문제이다.
VARCHAR(250) 으로 적용 해주면 에러가 발생하지 않는다.
### 2. 테이블 캐릭터셋을 utf8로 바꾼다
1번에서 얘기 했지만 utf8mb4는 이모지를 표현할 차세대 버전 인것 같다.
캐릭터셋은 바꾸지 않고 써보도록 하자.
### 3. 테이블 엔진을 MyISAM -> InnoDB로 바꾼다
1000 바이트 제하는 MyISAM 에만 해당한다. InnoDB가 최대 몇바이트 까지인지는 모르겠지만, VARCHAR(2000) 까진 해봤던적이 있다.
JPA 는 기본적으로 테이블 엔진의 설정을 MyISAM 으로 생성하는데, InnoDB로 바꾸는 방법은 아래 설정을 application.properties 에 넣어주면 된다.
```
spring.jpa.database-platform=org.hibernate.dialect.MySQL5InnoDBDialect
```
InnoDB도 방언 인가보다 ㅎㅎ Mysql만 해서그런가 뭐가 방언이고 표준인지 구분하는게 모호할때가 많다. JPA를 쓰면서 좀더 확인할수 있을것 같다.
### 결론
엔진을 굳이 MyISAM 을 쓸 필요가 없다면 InnoDB 로 바꿔서 쓰도록 하자.