Equals, HashCode in Jpa Entity

์ด ๊ธ€์€ ํŒ€์› June ์ž‘์„ฑํ–ˆ์Šต๋‹ˆ๋‹ค.

ํ…Œ์ŠคํŠธ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜๋˜ ๋„์ค‘, ๋‘ ์—”ํ‹ฐํ‹ฐ๊ฐ€ ๊ฐ™์€์ง€ ๋น„๊ตํ•˜๋Š” ์ฝ”๋“œ๊ฐ€ ๋งŽ์•„ Java์—์„œ ์“ฐ์ด๋Š” Equals, hahscode๊ฐ€ Jpa์—์„œ ์–ด๋–ป๊ฒŒ ์‚ฌ์šฉ๋  ์ˆ˜ ์žˆ๋Š”์ง€ ์•Œ์•„๋ณด์•˜์Šต๋‹ˆ๋‹ค.

Member member = new Member("nickname", "email", "1234");
Member member2 = new Member("nickname", "email", "1234");

assertThat(member).isEqualTo(member2);

๊ฐ™์€ ํ•„๋“œ๋ฅผ ์ง€๋‹ˆ๊ณ  ์žˆ๋‹ค๊ณ  ํ•ด์„œ member == member2 ์ผ๊นŒ์š”?

equals, hashcode๋ฅผ override๋ฅผ ํ•˜์ง€ ์•Š์•˜๋‹ค๋ฉด member, member2 ๊ฐ๊ฐ์˜ ์ธ์Šคํ„ด์Šค๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์œ„ ํ…Œ์ŠคํŠธ๋Š” ํ†ต๊ณผํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

Jpaํ™˜๊ฒฝ์—์„œ๋„ ์•Œ์•„๋ณด๊ณ  ์‹ถ๊ธฐ ๋•Œ๋ฌธ์— ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ ์•ˆ์—์„œ ๊ด€๋ฆฌ๋  ๋•Œ ํ™•์ธํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

@Autowired
MemberRepository memberRepository;

@Test
void EqualsAndHashCode() {
    memberRepository.save(new Member("nickname", "email", "1234"));
    Member member = memberRepository.findById(1L).get();
    Member member2 = memberRepository.findById(1L).get();
    em.clear();
    em.flush();

    assertThat(member).isEqualTo(member2);
}

์œ„ ์ฝ”๋“œ๋ฅผ ๋ณด๋ฉด ์–ด๋–ค ๊ฒฐ๊ณผ๊ฐ€ ๋‚˜์˜ฌ๊นŒ์š”?

member, member2๋Š” ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ์—์„œ ๊ด€๋ฆฌ๋˜๊ธฐ ๋•Œ๋ฌธ์— ์ฐธ์กฐ๊ฐ’์œผ๋กœ ๊ฐ™์€ ์ธ์Šคํ„ด์Šค์ธ์ง€ ํ™•์ธ์ด ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ํ…Œ์ŠคํŠธ๋ฅผ ํ†ต๊ณผํ•ฉ๋‹ˆ๋‹ค.

์˜์†์„ฑ ์ปจํ…์ŠคํŠธ์—์„œ ๊ด€๋ฆฌ๋˜์ง€ ์•Š๋Š” member๋Š” ์–ด๋–ป๊ฒŒ ๋ ๊นŒ์š”?

@Test
void EqualsAndHashCode() {
    memberRepository.save(new Member("nickname", "email", "1234"));
    Member member = memberRepository.findById(1L).get();
    Member member2 = memberRepository.findById(1L).get();
		em.detach(member);

    assertThat(member).isEqualTo(member2);
}

์œ„ ํ…Œ์ŠคํŠธ๋Š” ์‹คํŒจํ•ฉ๋‹ˆ๋‹ค. em.detach(member)๋กœ member๋Š” ์ค€์˜์† ์ƒํƒœ์ด๊ธฐ ๋•Œ๋ฌธ์— member2์™€ ๋‹ค๋ฅธ ์ฐธ์กฐ๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. member.getNickname() == member2.getNickname() ๋Š” True์ž…๋‹ˆ๋‹ค.

equals(), hashcode()

์œ„ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๋Š” ๋ฐฉ๋ฒ•์€ 3๊ฐ€์ง€๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

  1. PK๋กœ๋งŒ equals, hashCode ๊ตฌํ˜„

  2. PK๋ฅผ ์ œ์™ธํ•˜๊ณ  equla๋กœ ๊ตฌํ˜„

  3. ๋น„์ง€๋‹ˆ์Šค ํ‚ค๋ฅผ ์‚ฌ์šฉํ•œ ๋™๋“ฑ์„ฑ ๊ตฌํ˜„

1. PK๋กœ๋งŒ equls, hashCode ๊ตฌํ˜„ํ•˜๊ธฐ

@Override
public boolean equals(Object o) {
    if (this == o)
        return true;
    if (id == null) return false;
    if (!(o instanceof Member))
        return false;

    final Member user = (Member)o;

    return id.equals(Member.getId());
}

@Override
public int hashCode() {
    int result = id != null ? id.hashCode() : 0;
    return result;
}

์œ„ ์ฝ”๋“œ๋Š” Object๊ฐ€ Member์ธ์ง€ ํ™•์ธ ํ›„, pk์ธ Id๋ฅผ ๋น„๊ตํ•˜์—ฌ ๋™๋“ฑ์„ฑ์„ ๋น„๊ตํ•˜๋Š” ์ฝ”๋“œ์ž…๋‹ˆ๋‹ค.

์ด ๋ฐฉ๋ฒ•์€ repository.save() ์ฆ‰ PK๊ฐ€ ์ง€์ •๋œ ํ›„์—๋งŒ ๋น„๊ตํ•  ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ•์ž…๋‹ˆ๋‹ค.

์ฆ‰, ๊ฐ์ฒด์˜ ๋™๋“ฑ์„ฑ ๋น„๊ต๋ฅผ ์˜์†, ์ค€์˜์† ์ƒํƒœ์—์„œ๋งŒ ๋น„๊ตํ•˜๋Š”๊ฒŒ ๊ฐ€๋Šฅํ•œ ๋ฐฉ๋ฒ•์ž…๋‹ˆ๋‹ค.

2. PK๋ฅผ ์ œ์™ธํ•˜๊ณ  equals๋กœ ๊ตฌํ˜„

PK๋ฅผ ์ œ์™ธํ•œ ๋ชจ๋“  Field๋ฅผ ๋น„๊ตํ•˜๋Š” ๋ฐฉ๋ฒ•์ž…๋‹ˆ๋‹ค.

ํ•˜์ง€๋งŒ, Entity ๋‚ด๋ถ€์— join ๊ณผ ๊ฐ™์€ ๊ด€๊ณ„๊ฐ€ ์žˆ๋‹ค๋ฉด, ๋‹ค๋ฅธ ํ…Œ์ด๋ธ”๊ณผ ์—ฐ๊ด€๊ด€๊ณ„๊ฐ€ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ํฌํ•จํ•ด์„œ๋Š” ์•ˆ๋ฉ๋‹ˆ๋‹ค.

@Override
public boolean equals(Object o) {
    if (this == o)
        return true;
    if (!(o instanceof Member))
        return false;

    Member member = (Member)o;

    if (!Objects.equals(nickname, member.nickname))
        return false;
    if (!Objects.equals(email, member.email))
				return false;
		return Objects.equals(password, member.password);
}

@Override
public int hashCode() {
    int result = nickname != null ? nickname.hashCode() : 0;
    result = 31 * result + (email != null ? email.hashCode() : 0);
    result = 31 * result + (password != null ? password.hashCode() : 0);
    return result;
}

์œ„ ๋ฌธ์ œ๋Š” ์˜์†์„ฑ Context ์˜ instance ๋ฅผ ์ˆ˜์ •(๋งŒ์•ฝ ๋น„๋ฐ€๋ฒˆํ˜ธ๋ฅผ ๋ณ€๊ฒฝํ•œ๋‹ค๋ฉด) ๋‹ค๋ฅธ ์˜์†์„ฑ Context ์˜ instance ์™€๋Š” ๋” ์ด์ƒ ์ผ์น˜ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

3. ๋น„์ง€๋‹ˆ์Šค ํ‚ค๋ฅผ ์ด์šฉํ•œ ๋™๋“ฑ์„ฑ ๊ตฌํ˜„

PK๋ฅผ ์ œ์™ธํ•˜๊ณ  Unique๋ฅผ ์ œ์•ฝ ์กฐ๊ฑด์„ ๊ฐ€์ง„ email, ๋˜๋Š” ๋ณ€๊ฒฝ ๋ถˆ๊ฐ€๋Šฅํ•œ ์†์„ฑ ๋“ฑ์„ ์‚ฌ์šฉํ•˜๋ฉด ์œ„์˜ ๋ฐฉ๋ฒ•๋“ค์˜ ๋‹จ์ ์„ ๊ทน๋ณตํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Jpa ํ™˜๊ฒฝ์—์„œ equals(), hashcode()๋กœ ๋™๋“ฑ์„ฑ ๋น„๊ต์— ๋Œ€ํ•ด ์•Œ์•„๋ดค์Šต๋‹ˆ๋‹ค.

Last updated