인프런 커뮤니티 질문&답변
Entity와 MySQL 매핑 관련 질문 드립니다.
해결된 질문
작성
·
808
·
수정됨
0
안녕하세요.
Spring Boot 3.2.2 + MySQL 8.0 환경에서 JPA 학습 중 질문이 있습니다.
- Entity가 Enum 타입인 경우, MySQL Column 매핑은 어떤식으로 되어야 Best Practice 일까요? 
 학습 과정 중에서는 `@Column(columnDefinition = "char(1)")` Annotation으로 매핑 문제를 해결했습니다. 실무에서는 어떤 방식으로 정의하는지 알고 싶습니다. (e.g. Column 타입을 varchar(255)로 정의해서 사용한다. 아니면 DB 타입에 맞춰 Entity 정의하여 사용한다.)- Entity에서 사용된 Enum의 경우 'Y', 'N' 값만 정의되어 있습니다. - public enum BasicStatus { Y, N }
- MySQL Field 타입은 char(1)로 정의되어 있습니다. - @Entity @Getter @NoArgsConstructor(access = AccessLevel.PROTECTED) public class Destination extends BaseDatetimeEntity { // ... 중략 @Enumerated(EnumType.STRING) @Column(columnDefinition = "char(1)") private BasicStatus apartment; }
 
- Table을 직접 DDL로 생성 후, ddl-auto 옵션을 validate로 설정하여 서버를 실행하면 "Schema-validation: missing table [destination_seq]" 에러가 발생합니다. 해당 문제를 해결하기 위해 어떻게 접근하면 될까요? 그리고 실무에서는 Table 생성 시, JPA를 통한 생성을 하는 지 DDL로 생성하는지 궁금합니다. (DB 학습이 부족한 상황에서 질문 드리는 점 양해 부탁드립니다.) - Entity - @Entity @Getter @NoArgsConstructor(access = AccessLevel.PROTECTED) public class Member { @Id @GeneratedValue @Column(name = "member_id") private Long id; // ... 중략 @OneToMany(mappedBy = "member") private List<Destination> destinations = new ArrayList<>(); }- @Entity @Getter @NoArgsConstructor(access = AccessLevel.PROTECTED) public class Destination extends BaseDatetimeEntity { @Id @GeneratedValue @Column(name = "destination_id") private Long id; @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "member_id") private Member member; // ... 중략 }
- DDL - create table member ( member_id bigint unsigned auto_increment comment '회원 ID', # ... 중략 primary key (member_id) ); create table destination ( destination_id bigint unsigned auto_increment comment '배송지 ID', member_id bigint unsigned not null comment '회원 ID', # ... 중략 primary key (destination_id), foreign key (member_id) references member(member_id) );
- Error Log - org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.class]: [PersistenceUnit: default] Unable to build Hibernate SessionFactory; nested exception is org.hibernate.tool.schema.spi.SchemaManagementException: Schema-validation: missing table [destination_seq] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1773) ~[spring-beans-6.1.3.jar:6.1.3] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:599) ~[spring-beans-6.1.3.jar:6.1.3] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:521) ~[spring-beans-6.1.3.jar:6.1.3] at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:325) ~[spring-beans-6.1.3.jar:6.1.3] at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[spring-beans-6.1.3.jar:6.1.3] at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:323) ~[spring-beans-6.1.3.jar:6.1.3] at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199) ~[spring-beans-6.1.3.jar:6.1.3] at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1231) ~[spring-context-6.1.3.jar:6.1.3] at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:949) ~[spring-context-6.1.3.jar:6.1.3] at org.springframework.context.support.AbstractApplicationContext.__refresh(AbstractApplicationContext.java:624) ~[spring-context-6.1.3.jar:6.1.3] at org.springframework.context.support.AbstractApplicationContext.jrLockAndRefresh(AbstractApplicationContext.java:41002) ~[spring-context-6.1.3.jar:6.1.3] at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:42008) ~[spring-context-6.1.3.jar:6.1.3] at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:146) ~[spring-boot-3.2.2.jar:3.2.2] at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:754) ~[spring-boot-3.2.2.jar:3.2.2] at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:456) ~[spring-boot-3.2.2.jar:3.2.2] at org.springframework.boot.SpringApplication.run(SpringApplication.java:334) ~[spring-boot-3.2.2.jar:3.2.2] at org.springframework.boot.SpringApplication.run(SpringApplication.java:1354) ~[spring-boot-3.2.2.jar:3.2.2] at org.springframework.boot.SpringApplication.run(SpringApplication.java:1343) ~[spring-boot-3.2.2.jar:3.2.2] at kr.co.asasac.Application.main(Application.java:10) ~[main/:na] Caused by: jakarta.persistence.PersistenceException: [PersistenceUnit: default] Unable to build Hibernate SessionFactory; nested exception is org.hibernate.tool.schema.spi.SchemaManagementException: Schema-validation: missing table [destination_seq] at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.buildNativeEntityManagerFactory(AbstractEntityManagerFactoryBean.java:421) ~[spring-orm-6.1.3.jar:6.1.3] at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:396) ~[spring-orm-6.1.3.jar:6.1.3] at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.afterPropertiesSet(LocalContainerEntityManagerFactoryBean.java:352) ~[spring-orm-6.1.3.jar:6.1.3] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1820) ~[spring-beans-6.1.3.jar:6.1.3] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1769) ~[spring-beans-6.1.3.jar:6.1.3] ... 18 common frames omitted Caused by: org.hibernate.tool.schema.spi.SchemaManagementException: Schema-validation: missing table [destination_seq] at org.hibernate.tool.schema.internal.AbstractSchemaValidator.validateTable(AbstractSchemaValidator.java:134) ~[hibernate-core-6.4.1.Final.jar:6.4.1.Final] at org.hibernate.tool.schema.internal.GroupedSchemaValidatorImpl.validateTables(GroupedSchemaValidatorImpl.java:46) ~[hibernate-core-6.4.1.Final.jar:6.4.1.Final] at org.hibernate.tool.schema.internal.AbstractSchemaValidator.performValidation(AbstractSchemaValidator.java:97) ~[hibernate-core-6.4.1.Final.jar:6.4.1.Final] at org.hibernate.tool.schema.internal.AbstractSchemaValidator.doValidation(AbstractSchemaValidator.java:75) ~[hibernate-core-6.4.1.Final.jar:6.4.1.Final] at org.hibernate.tool.schema.spi.SchemaManagementToolCoordinator.performDatabaseAction(SchemaManagementToolCoordinator.java:295) ~[hibernate-core-6.4.1.Final.jar:6.4.1.Final] at org.hibernate.tool.schema.spi.SchemaManagementToolCoordinator.lambda$process$5(SchemaManagementToolCoordinator.java:145) ~[hibernate-core-6.4.1.Final.jar:6.4.1.Final] at java.base/java.util.HashMap.forEach(HashMap.java:1429) ~[na:na] at org.hibernate.tool.schema.spi.SchemaManagementToolCoordinator.process(SchemaManagementToolCoordinator.java:142) ~[hibernate-core-6.4.1.Final.jar:6.4.1.Final] at org.hibernate.boot.internal.SessionFactoryObserverForSchemaExport.sessionFactoryCreated(SessionFactoryObserverForSchemaExport.java:37) ~[hibernate-core-6.4.1.Final.jar:6.4.1.Final] at org.hibernate.internal.SessionFactoryObserverChain.sessionFactoryCreated(SessionFactoryObserverChain.java:35) ~[hibernate-core-6.4.1.Final.jar:6.4.1.Final] at org.hibernate.internal.SessionFactoryImpl.<init>(SessionFactoryImpl.java:315) ~[hibernate-core-6.4.1.Final.jar:6.4.1.Final] at org.hibernate.boot.internal.SessionFactoryBuilderImpl.__build(SessionFactoryBuilderImpl.java:450) ~[hibernate-core-6.4.1.Final.jar:6.4.1.Final] at org.hibernate.boot.internal.SessionFactoryBuilderImpl.build(SessionFactoryBuilderImpl.java:41010) ~[hibernate-core-6.4.1.Final.jar:6.4.1.Final] at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.__build(EntityManagerFactoryBuilderImpl.java:1507) ~[hibernate-core-6.4.1.Final.jar:6.4.1.Final] at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:40002) ~[hibernate-core-6.4.1.Final.jar:6.4.1.Final] at org.springframework.orm.jpa.vendor.SpringHibernateJpaPersistenceProvider.__createEntityManagerFactory(SpringHibernateJpaPersistenceProvider.java:75) ~[spring-orm-6.1.3.jar:6.1.3] at org.springframework.orm.jpa.vendor.SpringHibernateJpaPersistenceProvider.createContainerEntityManagerFactory(SpringHibernateJpaPersistenceProvider.java:40003) ~[spring-orm-6.1.3.jar:6.1.3] at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.__createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:376) ~[spring-orm-6.1.3.jar:6.1.3] at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:45002) ~[spring-orm-6.1.3.jar:6.1.3] at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.buildNativeEntityManagerFactory(AbstractEntityManagerFactoryBean.java:409) ~[spring-orm-6.1.3.jar:6.1.3] ... 22 common frames omitted
 
감사합니다.
답변 3
1
안녕하세요. Anonymous님, 공식 서포터즈 y2gcoder입니다.
- 결국 선택에 따라 다를 것 같습니다. DDL을 따로 만들 때 char(1) 로 설정해놨다면 저도 Anonymous 님과 같이 사용할 것 같습니다. 해당 enum의 모든 문자열 길이가 1로 고정되어있다면 해당 컬럼 타입이 맞을 것 같습니다! 다만 enum의 타입 길이가 각각 다르다면 varchar 타입을 고려해볼 것 같습니다 :) 
- 이건 바뀐 AUTO 정책과 관련이 있는 것 같습니다! 하이버네이트 버전이 올라감에 따라 AUTO 일 때의 기본 전략은 GenerationType.Table 로 변경되었습니다! 다음 링크(클릭)에서 확인해주시면 감사하겠습니다! 이거랑 추가로 스프링 부트 3.2.2 버전에서 사용하는 Hibernate 6.3 버전 문서(클릭)에서도 AUTO 전략에 대한 설명이 있습니다!  AUTO를 선택하면 DDL에 작성했던 autoincrement를 사용하지 않고 SEQUENCE, TABLE, UUID 중 하나를 사용한다고 합니다 :) AUTO를 선택하면 DDL에 작성했던 autoincrement를 사용하지 않고 SEQUENCE, TABLE, UUID 중 하나를 사용한다고 합니다 :)
감사합니다.
0

- "Schema-validation: missing table [destination_seq]" 에러는 - strategy = GenerationType.IDENTITY를 명시적으로 정의하여 해결되었습니다. 문제가 왜 발생하게 되었는지는 잘 모르겠습니다. 답변 부탁드리겠습니다~- 참고로 - @GeneratedValue의 기본값은- GenerationType.AUTO로 알고 있습니다. MySQL에서는- strategy = GenerationType.IDENTITY사용되는 걸로 알고 있습니다. identity 전략은 데이터베이스에 엔티티를 저장한 후 식별자 값을 가져와 영속성 컨텍스트에 저장하여 사용하는 걸로 알고 있습니다.
 
0
안녕하세요, 인프런 AI 인턴입니다. 질문자님의 경우 관련된 구체적인 케이스에 대한 답변을 찾기 위해, Entity와 Enum 타입, 그리고 DDL과 관련된 문제 해결 방법을 찾았습니다.
- Entity가 Enum 타입인 경우의 MySQL Column 매핑에 대한 Best Practice - 여기서 질문자님이 제시한 매핑 문제 해결 방법은 하나의 방안으로 볼 수 있으며, 실제로 다양한 방법이 있을 수 있습니다. 참고하면 좋을 유사한 질문으로, “MySQL enum 대소문자” 에 관한 내용이 있으며, 여기에서는 MySQL의 Enum 타입과 Java의 Enum 타입을 매핑하는 방법에 대한 토론이 있습니다. 하이버네이트가 데이터베이스와 클래스 필드를 매핑할 때 요구하는 타입이 상이하면 문제가 발생할 수 있는데, 이 경우에는 - @Enumerated(EnumType.STRING)애너테이션을 사용하면서 String 타입으로 변환을 하여 문제를 해결할 수 있습니다.- 마찬가지로 ”@Enumerated와 hibernate 타입 검증 관련” 질문에서는 Hibernate가 기대하는 Enum 타입과 실제 데이터베이스의 VARCHAR 타입 사이의 충돌 문제에 대한 논의가 있습니다. - @Column애너테이션과- @Enumerated(EnumType.STRING)애너테이션 사용을 통해 해결하는 예시를 찾을 수 있어 이는 질문자님의 상황에도 도움이 될 수 있습니다.
- DDL을 통한 Table 생성과 JPA 설정 문제 - Schema-validation 에러에 대한 질문은, - @GeneratedValue애너테이션 사용 방법 누락 또는 잘못된 사용으로 인한 것일 수 있습니다.- @GeneratedValue애너테이션은 기본적으로 기본키 생성을 위한 전략을 명시하는 데 사용됩니다. 만약- @GeneratedValue(strategy = GenerationType.SEQUENCE)와 같이 설정되어 있는 경우, Hibernate는 이에 해당하는 Sequence를 찾으려고 합니다. MySQL에서는 Sequence 대신 Auto Increment를 사용하는 것이 더 일반적이므로,- @GeneratedValue(strategy = GenerationType.IDENTITY)를 사용하여 문제를 해결할 수 있습니다. 이와 관련해서 “챕터6의 다양한 연관관계 매핑 - ManyToMany 전환작업시 질문드립니다.” 질문을 참고하시면 어느 정도 해결책을 얻을 수 있을 것 같습니다.
실무에서의 Best Practice는 환경과 팀의 정책에 따라 다양할 수 있으며, 일부 조직에서는 Entity 정의 시 DDL로 데이터베이스 스키마를 생성하고 ddl-auto 옵션을 update로 설정하거나, 매뉴얼로 테이블을 생성 후 validate로 설정하기도 합니다.
저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다.
현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏
추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.







감사합니다.