getClass()
关于getClass()
的用法,一切都很简单.
方法equals()
需要Object
类型的参数.
在执行强制转换和比较属性之前,确保您正在拨打same class的实例,这一点很重要,否则您可能会得到ClassCastException
.getClass()
可以用于此目的,如果对象不属于同一类,则它们显然不相等.
自然Id与代理Id
当你谈论"NaturalId"时,比如一本书的ISBN数字与"id",我猜你指的是一个持久性实体的natural key与关系数据库中使用的surrogate key.
在这一点上有不同的意见,一般建议的方法(see a link to the Hibernate user-guide and other references below)是在应用程序中使用natural id(一组独特的属性,也称为business keys)和实体在数据库中持久化only后获得的ID.
您可能会遇到基于surrogate id实现的hashCode()
和equals()
,并进行防御性空判断以防止实体处于瞬态且其id为null
的情况.根据这种实现,瞬态实体将不等于处于持久状态的实体,具有相同的属性(非空id除外).就我个人而言,我认为这种方法不正确.
以下代码示例取自最新的官方Hibernate 6.1 User-Guide
示例142.Natural Id equals/hashCode
@Entity(name = "Book")
public static class Book {
@Id
@GeneratedValue
private Long id;
private String title;
private String author;
@NaturalId
private String isbn;
//Getters and setters are omitted for brevity
@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);
}
@Override
public int hashCode() {
return Objects.hash(isbn);
}
}
与基于代理键的实现(称为naive implementation(see、Example 139
及更进一步))相比,上述使用业务键的代码在指南中表示为final approach.
Select ID vs Natural key的相同推理已在here中描述:
如果需要,则必须重写equals()和hashCode()方法
Hibernate保证持久标识(数据库行)的等价性
最明显的方法是通过比较
我们建议使用Business key
equality实现equals()和hashCode().
有关更多信息,请参阅最近由@Vlad Mihalcea compose 的(Sep 15, 2021)篇文章,内容涉及如何使用自然键The best way to map a @NaturalId business key with JPA and Hibernate改进缓存查询结果,以及以下问题: