private AccommodationType accommodationType;
JPA에서 ENUM을 쓸 때는 @Enumerated(EnumType.STRING) 이걸 지정해주는 게 좋다.
public enum AccommodationType {
HOTEL, GUESTHOUSE, MOTEL, PENSION, HANOK, APARTMENT
}
지정하지 않으면?
public class Accommodation {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(nullable = false)
private String name;
@Column(nullable = false)
private int price;
@Column(nullable = false)
private String address;
@Column(nullable = false)
private int maxCapacity;
@Column(nullable = false)
private int roomCount;
@Column(nullable = false)
private int bedCount;
@Column(nullable = false)
private String description;
@Column(nullable = false)
private String amenity;
private Long hostId;
private boolean isOnSale;
private double discountRate;
private AccommodationType accommodationType;
ENUM 어노테이션을 붙여주지 않으면 디폴트 값이 설정된다.
DB에 값을 넣을 때 숫자 형태로 넣어주어야 한다.
포스트맨으로 보낼 때는 그냥 ENUM 타입의 이름을 써주면 된다.
{
"name": "숙소6",
"price": 1000,
"address": "부천시 소사",
"maxCapacity": 2,
"roomCount": 2,
"bedCount": 1,
"description": "방이 예뻐요",
"amenity": "없음",
"hostId": 1,
"hastags": null,
"accommodationType": "MOTEL"
}
디비에는 위 사진처럼 값이 저장된다.
14번과 17번 칼럼은 포스트맨으로, 15,16은 DB에 직접 SQL문으로 값을 넣어주었다.
만약, ENUM 타입의 위치가 바뀐다면 어떻게 될까?
18번은 숙소 타입을 MOTEL해서 포스트맨으로 API 요청을 보냈다.
값은 0이 저장됐는데, 원래 0은 HOTEL이었고 MOTEL은 2였다.
유지보수할 때 ENUM 인스턴스의 순서가 변경되거나 새로운 타입을 추가하면 데이터 정합성이 어긋나버리는 것이다.
If the enumerated type is not specified or the Enumerated annotation is not used, the EnumType value is assumed to be ORDINAL.
공식문서에는 위처럼 적혀 있다. 타입을 명시해주지 않으면, enum 값의 순서를 명시하는 ordinal이 db에 저장된다는 것이다.
enum을 안전하게 쓰려면 타입을 명시해주는 게 좋다고 한다.
@Enumerated(EnumType.STRING)
private AccommodationType accommodationType;
{
"name": "숙소6",
"price": 1000,
"address": "부천시 소사",
"maxCapacity": 2,
"roomCount": 2,
"bedCount": 1,
"description": "방이 예뻐요",
"amenity": "없음",
"hostId": 1,
"hastags": null,
"accommodationType": "MOTEL"
}
포스트맨으로 MOTEL로 값을 보냈을 때 String 형태 그대로 저장이 된다.
enum 타입의 순서가 바뀌거나, 새로운 타입을 추가해도 순서의 값을 저장하지 않으니 유지보수 관점에서 문제가 없을 듯하다.
String으로 명시를 해주니 db에 넣어 두었던 값들이 String 타입으로 변했다.
참고로 enum 타입을 사용한 건
우리 팀이 숙소 타입으로 지정해둔 것들만 등록할 수 있게끔 하기 위해서다.
{
"name": "숙소6",
"price": 1000,
"address": "부천시 소사",
"maxCapacity": 2,
"roomCount": 2,
"bedCount": 1,
"description": "방이 예뻐요",
"amenity": "없음",
"hostId": 1,
"hastags": null,
"accommodationType": "a"
}
이렇게 값을 넣어서 api를 호출하면
com.fasterxml.jackson.databind.exc.InvalidFormatException: Cannot deserialize value of type `codesquad.team05.domain.accomodation.AccommodationType` from String "a": not one of the values accepted for Enum class: [HANOK, APARTMENT, HOTEL, GUESTHOUSE, MOTEL, PENSION]
at [Source: REDACTED (`StreamReadFeature.INCLUDE_SOURCE_IN_LOCATION` disabled); line: 12, column: 26] (through reference chain: codesquad.team05.web.accommodation.dto.request.AccommodationSave["accommodationType"])
위와 같은 에러가 뜬다!