인프런 영문 브랜드 로고
인프런 영문 브랜드 로고

인프런 커뮤니티 질문&답변

yeon님의 프로필 이미지
yeon

작성한 질문수

자바 ORM 표준 JPA 프로그래밍 - 기본편

기본 키 매핑

@GeneratedValue 사용 후 DDL 실패

작성

·

4.8K

1

학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.

1. 강의 내용과 관련된 질문을 남겨주세요.
2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.
(자주 하는 질문 링크: https://bit.ly/3fX6ygx)
3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.
(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)

질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.
=========================================
[질문 템플릿]
1. 강의 내용과 관련된 질문인가요? (예/)
2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/)
3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/)

[질문 내용]
h2는 1.4.199를 사용합니다
User 테이블이 생성되어야 할 것 같은데 생성 실패하는 이유가 뭘까요?
(User 테이블이 아니라 강의를 똑같이 따라한 Member에서 id를 @GeneratedValue해도 같은 오류가 나타납니다)

persistence.xml
<?xml version="1.0" encoding="UTF-8"?>
<!--jpa 설정 파일-->
<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"/>
<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>
 
User.java
package hellojpa;

import javax.persistence.*;

@Entity
public class Users {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private String id;

@Column
private String name;

public Users() {
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public String getId() {
return id;
}

public void setId(String id) {
this.id = id;
}
}
 
오류내역
Hibernate: 
    
    create table User (
       id varchar(255) generated by default as identity,
        name varchar(255),
        primary key (id)
    )
1월 01, 2022 6:05:00 오후 org.hibernate.tool.schema.internal.ExceptionHandlerLoggedImpl handleException
WARN: GenerationTarget encountered exception accepting command : Error executing DDL "
    create table User (
       id varchar(255) generated by default as identity,
        name varchar(255),
        primary key (id)
    )" via JDBC Statement
org.hibernate.tool.schema.spi.CommandAcceptanceException: Error executing DDL "
    create table User (
       id varchar(255) generated by default as identity,
        name varchar(255),
        primary key (id)
    )" via JDBC Statement
	at org.hibernate.tool.schema.internal.exec.GenerationTargetToDatabase.accept(GenerationTargetToDatabase.java:67)
	at org.hibernate.tool.schema.internal.AbstractSchemaMigrator.applySqlString(AbstractSchemaMigrator.java:559)
	at org.hibernate.tool.schema.internal.AbstractSchemaMigrator.applySqlStrings(AbstractSchemaMigrator.java:504)
	at org.hibernate.tool.schema.internal.AbstractSchemaMigrator.createTable(AbstractSchemaMigrator.java:277)
	at org.hibernate.tool.schema.internal.GroupedSchemaMigratorImpl.performTablesMigration(GroupedSchemaMigratorImpl.java:71)
	at org.hibernate.tool.schema.internal.AbstractSchemaMigrator.performMigration(AbstractSchemaMigrator.java:207)
	at org.hibernate.tool.schema.internal.AbstractSchemaMigrator.doMigration(AbstractSchemaMigrator.java:114)
	at org.hibernate.tool.schema.spi.SchemaManagementToolCoordinator.performDatabaseAction(SchemaManagementToolCoordinator.java:183)
	at org.hibernate.tool.schema.spi.SchemaManagementToolCoordinator.process(SchemaManagementToolCoordinator.java:72)
	at org.hibernate.internal.SessionFactoryImpl.<init>(SessionFactoryImpl.java:310)
	at org.hibernate.boot.internal.SessionFactoryBuilderImpl.build(SessionFactoryBuilderImpl.java:467)
	at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:939)
	at org.hibernate.jpa.HibernatePersistenceProvider.createEntityManagerFactory(HibernatePersistenceProvider.java:56)
	at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:79)
	at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:54)
	at hellojpa.MappingMain.<clinit>(MappingMain.java:9)
Caused by: org.h2.jdbc.JdbcSQLSyntaxErrorException: Syntax error in SQL statement "\000d\000a    CREATE TABLE USER[*] (\000d\000a       ID VARCHAR(255) GENERATED BY DEFAULT AS IDENTITY,\000d\000a        NAME VARCHAR(255),\000d\000a        PRIMARY KEY (ID)\000d\000a    )"; expected "identifier"; SQL statement:

    create table User (
       id varchar(255) generated by default as identity,
        name varchar(255),
        primary key (id)
    ) [42001-204]
	at org.h2.message.DbException.getJdbcSQLException(DbException.java:521)
	at org.h2.message.DbException.getJdbcSQLException(DbException.java:496)
	at org.h2.message.DbException.getSyntaxError(DbException.java:265)
	at org.h2.command.Parser.readIdentifier(Parser.java:6080)
	at org.h2.command.Parser.readIdentifierWithSchema(Parser.java:6040)
	at org.h2.command.Parser.readIdentifierWithSchema(Parser.java:6069)
	at org.h2.command.Parser.parseCreateTable(Parser.java:10325)
	at org.h2.command.Parser.parseCreate(Parser.java:7811)
	at org.h2.command.Parser.parsePrepared(Parser.java:1140)
	at org.h2.command.Parser.parse(Parser.java:1068)
	at org.h2.command.Parser.parse(Parser.java:1037)
	at org.h2.command.Parser.prepareCommand(Parser.java:965)
	at org.h2.engine.SessionLocal.prepareLocal(SessionLocal.java:624)
	at org.h2.server.TcpServerThread.process(TcpServerThread.java:288)
	at org.h2.server.TcpServerThread.run(TcpServerThread.java:191)
	at java.lang.Thread.run(Unknown Source)

	at org.h2.message.DbException.getJdbcSQLException(DbException.java:451)
	at org.h2.engine.SessionRemote.done(SessionRemote.java:607)
	at org.h2.command.CommandRemote.prepare(CommandRemote.java:85)
	at org.h2.command.CommandRemote.<init>(CommandRemote.java:51)
	at org.h2.engine.SessionRemote.prepareCommand(SessionRemote.java:477)
	at org.h2.jdbc.JdbcConnection.prepareCommand(JdbcConnection.java:1292)
	at org.h2.jdbc.JdbcStatement.executeInternal(JdbcStatement.java:217)
	at org.h2.jdbc.JdbcStatement.execute(JdbcStatement.java:205)
	at org.hibernate.tool.schema.internal.exec.GenerationTargetToDatabase.accept(GenerationTargetToDatabase.java:54)
	... 15 more

1월 01, 2022 6:05:00 오후 org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl stop
INFO: HHH10001008: Cleaning up connection pool [jdbc:h2:tcp://localhost/~/test]

Process finished with exit code 0
 

답변 6

3

김영한님의 프로필 이미지
김영한
지식공유자

안녕하세요. yeonLog님

테이블에서 자동생성되는 ID의 타입은 숫자 타입이어야 합니다.

감사합니다.

yeon님의 프로필 이미지
yeon
질문자

안녕하세요 김영한님! 

위에 먼저 답변해주셨던 OMG님의 실행 로그를 보면 String으로도 생성은 가능한 것 같습니다

(제가 String으로 테스트 할 때는 실패가 뜨긴 합니다...)

'ID의 타입은 숫자 타입이어야 한다'는 권장사항 인가요??

김영한님의 프로필 이미지
김영한
지식공유자

아닙니다. String을 사용하면 안됩니다. 숫자 타입이어야 합니다.

'기본키맵핑'강의 3:54에서는 String으로 선언하시고 GenerationType.IDENTITY 로 잘 작동하는 것을 보여주셨습니다.

강의 내용과 위 답변에 어떤 차이가 있는지 궁금합니다.

김영한님의 프로필 이미지
김영한
지식공유자

안녕하세요. ddoddo님

GenerationType.IDENTITY로 해서 String을 사용했다면 강의 내용이 잘못되었습니다. String으로 정상 동작한다고 할지라도 숫자 타입의 경우 Long으로 설정하는 것이 맞습니다.

감사합니다.

1

yeon님의 프로필 이미지
yeon
질문자

+ 해당 문제 해결했습니다

H2에서 User가 예약어였던건지 Users로 이름을 변경하니까 위 문제는 해결했습니다! 다만 아래 에러가 새롭게 발생했습니다ㅠ_ㅜ

Caused by: org.h2.jdbc.JdbcSQLFeatureNotSupportedException: Feature not supported: "CHARACTER VARYING(255)"; SQL statement:

    create table Users (
       id varchar(255) generated by default as identity,
        name varchar(255),
        primary key (id)
    ) [50100-204]

전체 코드: https://github.com/yeon-06/inflearnSpring/tree/master/jpa-ex1

0

저도 막혔는데 Long으로 써야 하는군요.

0

안녕하세요 yeonLog님

혹시 아이디를 String이 아닌 Long으로 변경해서 다시 시도해보면 어떨까요?

yeon님의 프로필 이미지
yeon
질문자

안녕하세요 codesweaver님 답변 감사합니다!

Long으로 하는 경우에는 동작합니다

다만 위의 OMG님이 제 코드를 실행시키셨을 때는 String으로 하는 경우에도 동작하시는 것으로 보입니다

무슨 차이인지 모르겠네요 ㅜ0ㅜ

0

안녕하세요. yeonLog님, 공식 서포터즈 OMG입니다.

아래 링크 영한님 말씀처럼 테이블 drop 후 시도해주세요. 별 다른 수정 없이 테스트 하였는데 정상 작동하였습니다.

테이블 drop 후 안될 경우 test db가 아닌 jdbc:h2:tcp://localhost/~/test2

와 같이 새로운 db를 생성하여 진행해주세요.

@GeneratedValue 사용 후 DDL 실패 - 인프런 | 질문 & 답변 (inflearn.com)

 




감사합니다.

yeon님의 프로필 이미지
yeon
질문자

안녕하세요 주말에도 빠른 답변 주셔서 감사합니다!

말씀해주신 drop 후 시도, DB를 새로 생성 후 시도 둘 다 해보았으나 여전히 같은 오류가 발생합니다ㅠㅠ

혹시 다른 예상 원인이 있으실까요?

 

Caused by: org.h2.jdbc.JdbcSQLFeatureNotSupportedException: Feature not supported: "CHARACTER VARYING(255)"; SQL statement:

yeon님의 프로필 이미지
yeon
질문자

추가로 @GenereatedValue가 AUTO, SEQUENCE인 경우에는 괜찮지만 IDENTITY에서만 해당 오류가 발생합니다. h2 DB에 문제가 있는 것이라고 생각되는데 h2에서 auto increment같은 기능을 사용하려면 별도로 설정을 바꿔줘야 할까요?

스프링 입문편에서의 data.sql을 참고하시면 H2에서 IDENTITY사용을 보실수 있습니다.

 

yeon님의 프로필 이미지
yeon
질문자

해당 강의 확인하였으나 h2의 설정을 별도로 바꾼 것은 없어보입니다.

다만 id의 자료형을 String -> Long으로 변경하니 정상 작동이 되었습니다.

DDL에서 varchar(255)가 아닌 bigint로 선언되어 통과된 것으로 보입니다.

 

OMG님의 실행 화면을 보면 varchar(255)일 때도 작동된 것 같은데...

h2에서 아래 쿼리문을 직접 실행시키려고 했더니 오류가 발생합니다.

create table Users (
       id varchar(255) generated by default as identity,
        name varchar(255),
        primary key (id)
    )

 

오류내역

Feature not supported: "CHARACTER VARYING(255)"; SQL statement:
create table Users (
       id varchar(255) generated by default as identity,
        name varchar(255),
        primary key (id)
    ) [50100-204]
 HYC00/50100 

yeon님의 프로필 이미지
yeon

작성한 질문수

질문하기