Spring(boot)

[SpringBoot] @EqualsAndHashCode 어노테이션 알아보기

p.guns23 2025. 1. 15. 17:05

들어가기 

Dto객체에 Lombok을 활용하여 어노테이션을 사용하던 중 아래와 같은 경고가 발생하였다. 

warning: Generating equals/hashCode implementation but without a call to superclass, even though this class does not extend java.lang.Object. If this is intentional, add '@EqualsAndHashCode(callSuper=false)' to your type.
@Data
^
1 warning

해당 경고가 발생되는 원인가 해결법을 알아보자. 

 

확인해 보기 

상황설정 

MemberDto.java

@Data
public class MemberDto {

  private String name; //이름
  private String address; //사는곳
}

OldMemberDto.java

@Data
public class OldMemberDto extends MemberDto {

  private int birthDate; //생년월일
}

DtoTest.java

@Test
  void dtoTest() {

    //given
    OldMemberDto member1 = new OldMemberDto();
    member1.setName("김길동");
    member1.setAddress("서울시");
    member1.setBirthDate(196700111);

    OldMemberDto member2 = new OldMemberDto();
    member2.setName("홍길동");
    member2.setAddress("서울시");
    member2.setBirthDate(196700111);

    //when then
    //테스트 결과 → fail 
    Assertions.assertFalse(member1.equals(member2));
  }

- 위 테스트 코드를 확인하였을 때, '김길동'의 객체와 '홍길동'의 객체가 같다는 결과가 나오고 있다. (잘못됨)

 

발생원인

1. @Data 어노테이션은 아래와 같이 여러 개의 어노테이션을 포함하고 있다.
  - @Getter, @Setter, @RequiredArgsConstructor, @ToString, @EqualsAndHashCode
 
2. @EqualsAndHashCode 어노테이션의 역활
  - equals와 hashCode 메서드를 생성함.
        - equals() : 두 객체의 내용이 같은지 확인하는 함수.
         - hashCode() : 두 객체가 동일한 객체인지 확인하는 함수
  - 두 객체가 같은지 비교하거나 해시값을 계산할 때 사용됨.
    
3. 경고 원인 - 상속구조
  - '@Data' 어노테이션 사용으로 상속 구조에서는 부모클래스의 필드만 EqualsAndHashCode를 생성할지, 자식 클래스만 대상으로 생성할지 Lombok은 불분명함. 
  - 우선적으로 Lombok에서는 부모 필드만으로 생성하여 만들긴 하지만, 위와 같이 경고를 띄어줌. 
  - 부모필드로만 생성되기 때문에 위의 테스트코드의 결과값이 fail되고 있음. 
 

해결방법

'@EqualsAndHashCode(callSuper=true)' 사용하기 

@Data
@EqualsAndHashCode(callSuper = true)
public class OldMemberDto extends MemberDto {

  private int birthDate; //생년월일
}

- 부모클래스에 '@EqualsAndHashCode' 어노테이션을 사용. 

- 해당 어노테이션으로 자식 클래스의 필드를 포함하도록 설정. 

 

끝으로

@Data를 사용할 때는 내가 사용하지 않는 어노테이션도 있기에 예상치 못한 상황이 발생할 수도..

상황에 맞게 필요한 어노테이션을 명시해서 사용하자!