gpt4 book ai didi

java - 如何使用 @NaturalId 正确覆盖 Hibernate 实体的 equals

转载 作者:行者123 更新时间:2023-12-02 01:37:37 29 4
gpt4 key购买 nike

已经多次讨论过如何为Entity重新定义equals/hashCode。

我的问题是需要使用 equals 中的所有字段。考虑两种情况。

当我们使用等于的所有字段时:

@Entity
public class Book {

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

@NaturalId
@Column(name = "isbn", nullable = false, unique = true)
private String isbn;

@Column
private String name;

private Book() {
}

public Book(String isbn) {
this.isbn = isbn;
}

@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Book book = (Book) o;
return Objects.equals(id, book.id) &&
Objects.equals(isbn, book.isbn) &&
Objects.equals(name, book.name);
}

@Override
public int hashCode() {
return Objects.hash(isbn);
}
}

并测试:

public class BookTest1 {

@PersistenceContext
protected EntityManager em;

@Test
public void fromTransientToManageSameEntity() {
Book book1 = new Book("4567-5445-5434-3212");
Book book2 = new Book("4567-5445-5434-3212");

em.persist(book2);
flushAndClean();

assertThat(book1, is(not((equalTo(book2))))); // not equals
}
}

正如我们所见,当将实体从 transient 转换为管理状态时 - 相同的实体将不相等。

另一种情况是当我们仅在 equals 中使用 @NaturalId 时:

@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Book book = (Book) o;
return Objects.equals(isbn, book.isbn);
}

并测试:

public class BookTest2 {

@PersistenceContext
protected EntityManager em;

@Test
public void fromTransientToManageSameEntity() {
Book book1 = new Book("4567-5445-5434-3212");
Book book2 = new Book("4567-5445-5434-3212");

em.persist(book2);
flushAndClean();

assertThat(book1, equalTo(book2)); // equals
}
}

正如我们所见,现在两个实体将是平等的。

我的问题是同一实体在管理状态的过渡中是否应该平等。以及在这种情况下如何正确地重新定义 equals。

最佳答案

根据this article equalshashCode应该是与状态无关的。如果您只覆盖了第一个,那就很糟糕并且可能会导致奇怪的错误。他们需要有一个 contract

最简单的方法是使用 lombok - 用 @EqualsAndHashCode(onlyExplicitlyIncluded = true, callSuper = false) 注释你的类以及与@EqualsAndHashCode.Include相比使用的字段.

关于java - 如何使用 @NaturalId 正确覆盖 Hibernate 实体的 equals,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54990846/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com