JPA 엔티티의 AttributeConverter를 사용하는 값 객체에 대하여 equals / hashCode를 재정의 해주자

라빈·2022년 8월 25일
0

프로젝트 기술 스택

  • spring-data-jpa 2.3
  • Hibernate core 5.4

문제

JPA 엔티티에 collection을 다루기 위한 일급 컬렉션을 정의했다. 해당 일급 컬렉션을 데이터베이스에 저장할 때 비즈니스 요구사항으로 인해 converter를 사용해 특정 형식으로 저장하려고 한다. 이때 일급 컬렉션에 equals / hashCode를 정의하지 않은 상태에서 애플리케이션을 실행하면 다음과 같은 warn 로그가 발생한다. → 일급 컬렉션과 같은 모든 값 객체를 데이터베이스에 custom converter를 사용하여 데이터 형식을 변환해서 저장하려 할 때 발생하는 로그다.

예시 코드

@Getter
@Entity
public class Order {

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

    @Column(columnDefinition = "json")
    @Convert(converter = MenuGroupConverter.class)
    private MenuGroup menuGroup;

    @Getter
    public static class MenuGroup {

        private Set<String> menus;
    }

    protected Order() {
    }
}
HHH000481: Encountered Java type [class com.example.jpapractice.transactional.domain.entity.Order$MenuGroup] for which we could not locate a JavaTypeDescriptor and which does not appear to implement equals and/or hashCode.  This can lead to significant performance problems when performing equality/dirty checking involving this Java type.  Consider registering a custom JavaTypeDescriptor or at least implementing equals/hashCode.

로그 발생 원인

엔티티의 동등성 비교(equality) / 더티 체킹을 수행할 때 값 객체의 경우 equals / hashCode를 사용한다.

  • 하지만 값 객체에 해당 메서드를 재정의하지 않았다.
  • 만약 custom converter를 사용하여 데이터베이스에 값 객체를 변환해 저장하는 경우 값 객체에 확장한 AttributeConverter의 구현 로직을 이용해 동등성 비교 / 더티 체킹을 수행한다.

따라서 성능 문제가 발생할 수 있고 이것에 대한 경고를 주는 것이다.

값 객체가 아닌 기본 JDK 타입에 대한 비교

Hibernate에서 자바의 객체를 변환해서 저장할 때 변환 과정을 거치는데 직렬화 가능한(serializable 구현) 기본적인 자바 타입에 대한 JavaTypeDescriptorJavaTypeDescriptorRegistry에 등록되어있다.

우리가 엔티티에서 사용하는 값 객체들에 대해서는 JavaTypeDescriptor를 구현하지 않고 JavaTypeDescriptorRegistry에도 등록하지 않는다. 따라서 Hibernate가 값 객체를 JDBC 레벨에서 어떻게 다뤄야 하는지 알지 못한다.

추가적으로 확인할 사항

  • Hibernate의 영속성 컨텍스트 안에서 동등성 비교 / 더티 체킹 로직을 직접 확인해보자.

참고

profile
작은 개발지식부터 공유해요 :)

0개의 댓글