사용자 도구

사이트 도구


java:jpa:converter

JPA Converter

  • JPA 2.1 에서 생긴 개념.
  • Hibernate User Type 보다 간결하게 엔티티 필드 객체와 DB 타입간 변환이 가능하다. 물론 기능은 다소 부족할 수 있으나 대부분의 경우를 만족시켜줄 수 있다.
  • @Id 컬럼에 대해서는 Converter 사용이 불가하다(JPA 명세에 불가하다고 나옴). Hibernate User Type 사용해야 할 것 같다.
@Converter
public class PersonNameConverter implements AttributeConverter<PersonName, String> {
 
    @Override
    public String convertToDatabaseColumn(PersonName personName) {
        // object to DB column 구현
    }
 
    @Override
    public PersonName convertToEntityAttribute(String dbPersonName) {
       // DB column to object 구현
}
 
@Entity(name = "PersonTable")
public class Person {
 
    @Convert(converter = PersonNameConverter.class)
    private PersonName personName;
 
    // ...
}

변환 클래스에 equals & hashCode 구현 필수

  • AttributeConverter의 컨버팅 대상이 되는 클래스에 equals, hashCode 메소드를 명확히 구현할 것.
  • Hibernate의 경우, Dirty Checking 시에 최초 생성된 객체를 복사해서 따로 저장하고 이후에 복사본과 마지막 상태를 equals 로 비교한다. 따라서 equals/hashCode가 복사시마다 달라지는 경우에 문제 소지가 있다.
  • 이때 첫 값과 두번째 값의 equals를 보고서 dirty checking 을 하는데, equals가 제대로 구현 안돼 있으면 false가 나오고 그로인해 entity 전체에 대한 update 가 발생한다.
  • 따라서 Java 기본형들이 아닌 custom class 로 convert 할 경우에는 필히 equals/hashCode를 구현해야 한다. 그렇지 않으면 모르는 사이에 지속적으로 update가 발생하게 된다.

잘못된 Colum Type 매핑

  • AttributeConverter 를 사용하여 String, Number 같은 다소 광의의 타입을 명시적 비즈니스 도메인 타입으로 매핑했을 때(예: ISBN), 보통 해당 타입이 Serializable을 구현하면서 Hibernate가 무조건 VARBINARY로 매핑하는 버그가 있다(현재 5.2.x 버전도 마찬가지)
  • 이때 StandardBasicTypes.java에 나온 타입들을 명시적으로 지정해주면 된다.
@Convert(converter=ISBNConverter.class)
@org.hibernate.annotations.Type(type="string")
private ISBN isbn;
java/jpa/converter.txt · 마지막으로 수정됨: 2022/11/18 15:05 저자 kwon37xi