MySQL의 smallint를 Java에 Entity Column과 mapping 하는 방법
다음과 같이 columnDefinition에 smallint를 추가해주시면 됩니다.
@Column(name = "year", columnDefinition = "smallint")
private Integer year;
columnDefinition이란?
columnDefinition은 엔티티의 클래스의 필드가 데이터베이스의 컬럼으로 매핑될 때 사용하는 어노테이션입니다.
주된 목적은 데이터베이스의 고유한 타입이나 제약 조건을 지정할 때 유용합니다.
위에 작성한 예제처럼 Java의 Integer를 smallint과 매핑하는 경우도 가능하고 아래처럼 제약사항을 걸 수도 있습니다.
@Column(name = "example_column", columnDefinition = "VARCHAR(100) DEFAULT 'N/A'")
private String example;
smallint를 Integer에 매핑할때 columnDefinition을 지정하는 이유
smallint는 범위가 -32,768 ~ 32,767입니다.
Java의 Integer 범위는 -2^31부터 2^31 - 1입니다.
-2,147,483,648부터 2,147,483,647인데, 대부분의 개발자들이 21억정도 된다고 이해하고 있습니다.
만약 지정하지 않으면 두 타입의 범위가 안맞아서 다음과 같은 SchemaManagementException이 발생합니다.
Caused by: org.hibernate.tool.schema.spi.SchemaManagementException: Schema-validation: wrong column type encountered in column [year] in table [users]; found [smallint (Types#SMALLINT)], but expecting [integer (Types#INTEGER)]
at org.hibernate.tool.schema.internal.AbstractSchemaValidator.validateColumnType(AbstractSchemaValidator.java:165) ~[hibernate-core-6.2.9.Final.jar:6.2.9.Final]
at org.hibernate.tool.schema.internal.AbstractSchemaValidator.validateTable(AbstractSchemaValidator.java:152) ~[hibernate-core-6.2.9.Final.jar:6.2.9.Final]
at org.hibernate.tool.schema.internal.GroupedSchemaValidatorImpl.validateTables(GroupedSchemaValidatorImpl.java:46) ~[hibernate-core-6.2.9.Final.jar:6.2.9.Final]
at org.hibernate.tool.schema.internal.AbstractSchemaValidator.performValidation(AbstractSchemaValidator.java:97) ~[hibernate-core-6.2.9.Final.jar:6.2.9.Final]
at org.hibernate.tool.schema.internal.AbstractSchemaValidator.doValidation(AbstractSchemaValidator.java:75) ~[hibernate-core-6.2.9.Final.jar:6.2.9.Final]
at org.hibernate.tool.schema.spi.SchemaManagementToolCoordinator.performDatabaseAction(SchemaManagementToolCoordinator.java:293) ~[hibernate-core-6.2.9.Final.jar:6.2.9.Final]
at org.hibernate.tool.schema.spi.SchemaManagementToolCoordinator.lambda$process$5(SchemaManagementToolCoordinator.java:143) ~[hibernate-core-6.2.9.Final.jar:6.2.9.Final]
columnDefinition 주의사항
columnDefinition은 사용할 때 주의가 필요합니다. 당장 작성한 smallint만 보아도 MySQL에 종속적인 타입입니다.
이런식으로 특정 데이터베이스에 종속적인 정의를 만들 수 있기 때문에, 나중에 데이터베이스를 변경하고 싶을때 생각치 못한 문제가 발생할 수 있습니다. 만약 꼭 필요한 상황이 아니라면, JPA에서 지원하는 표준타입과 어노테이션을 사용하는게 좋을 수 있습니다.
columnDefinition을 사용하지 않는 방법
columnDefinition을 사용하지 않는 방법은 Java의 short를 사용하면 됩니다.
Java의 short는 범위가 -32,768 ~ 32,767로, MySQL smallint랑 같아서 columnDefinition을 입력하지 않아도 정상적으로 mapping 됩니다. 하지만 이 방법은 잘 사용하지 않습니다.
Java에서 short를 사용하지 않는 이유
JVM의 피연산자 스택은 int(32비트, 4바이트) 타입의 연산을 기본 단위로 사용합니다.
즉 short(16비트,2바이트)와 같은 데이터도 내부적으로 4바이트 단위로 형변환 후 사용해서 불필요한 타입변환이 일어납니다.
실제로 2바이트를 담으려고 했지만 4바이트로 저장되기 때문에 메모리의 이점도 없습니다.
그 외에는 대부분의 라이브러리나 프레임워크가 int or long을 사용하기 때문에 추가적인 형변환이 발생해서 비효율적입니다.
'JPA' 카테고리의 다른 글
[QueryDSL] Pageable 정렬하기 (0) | 2024.02.14 |
---|