본문 바로가기

DevelopNote/오류 모음

Spring + Hibernate enum 타입 문제 해결

 

[문제]

  • Hibernate 사용 시 entityManagerFactory를 생성 하는 과정에서 오류 발생
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: wrong column type encountered in column [indicator] in table [question]; found [enum (Types#CHAR)], but expecting [varchar(255) (Types#VARCHAR)].

 


[원인]

  • 오류 메시지를 봤을 때 question 테이블의 indecator 열에서 문제가 발생 확인
  • 데이터베이스 스키마는 indicator 열 데이터 타입이 enum 으로 정의 되어있었으나, Htibernate는 varchar로 확인하고 있었다.
@Getter
@Entity
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class Question {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private  Long id;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "category_id", nullable = false)
    private Category category;

    @OneToMany(mappedBy = "question")
    private List<Answer> answer;

    @Enumerated(EnumType.STRING)
    @Column(columnDefinition = "enum")
    private MbtiIndicator indicator;

    private String content;
}
  • 해당되는 Table의 Entity인데 MbtIiIndicator 객체는 @Enumerated(EnumType.STRING) 어노테이션을 사용해서 Enum 타입을 데이터베이스 문자열로 저장 했다.
  • 그러나 Hibernate는 indicator 열의 데이터 타입을 varchar(255)로 예상하고 있어 오류가 발생했다.

 


[해결 방법]

  • @Column(columnDefinition = "enum") 어노테이션을 사용해 데이터베이스를 Enum 형태로 설정하여 문제를 해결 했다.
    @Enumerated(EnumType.STRING)
    @Column(columnDefinition = "enum")
    private MbtiIndicator indicator;
  • 단, Enum 은 다른 데이터베이스에서 지원하지 않을 수 있어 문제가 발생할 수 있다.

[추가 해결 방법]

  • @Convert 어노테이션 사용
    • @Convert 어노테이션으로 Enum 값을 원하는 데이터 타입으로 변환할 수 있다.
    @Converter
    public class MbtiIndicatorConverter implements AttributeConverter<MbtiIndicator, String> {
    
        @Override
        public String convertToDatabaseColumn(MbtiIndicator attribute) {
            // Enum 값을 문자열로 변환하여 데이터베이스에 저장
            return attribute.name();
        }
    
        @Override
        public MbtiIndicator convertToEntityAttribute(String dbData) {
            // 데이터베이스에서 읽어온 문자열을 Enum 값으로 변환
            return MbtiIndicator.valueOf(dbData);
        }
    }
    

 


[기타]

  • Hibernate?
    • 자바 언어로 작성된 ORM 프레임워크로, 객체들과 데이터베이스의 테이블과 같은 관계형 데이터베이스 사이의 데이터를 자동으로 매핑해주는 기술
300x250