多应用+插件架构,代码干净,二开方便,首家独创一键云编译技术,文档视频完善,免费商用码云13.8K 广告
# Hiberate 实体等价和等同 > 原文: [https://howtodoinjava.com/hibernate/hibernate-entities-equality-and-identity/](https://howtodoinjava.com/hibernate/hibernate-entities-equality-and-identity/) 在我们的应用中,很多时候我们都面临着这样的情况,我们必须比较两个对象以检查它们的相等性以满足某些业务规则。 在核心 Java 中,我们已经掌握了检查对象是否相等的知识,但是在 Hiberate 下,我们还需要注意一些额外的事情。 让我们了解一下那些额外的概念。 我们已经了解了 Hiberate 实体在其生命周期中的各种[**状态**](//howtodoinjava.com/hibernate/hibernate-entity-persistence-lifecycle-states/ "Hibernate Entity / Persistence LifeCycle States")。 在那里,我们讨论了 Hiberate 大多数仅适用于持久对象。 众所周知,当我们在 hibernate 中有一个持久对象时,该对象代表了两个: * 特定 Java 虚拟机(JVM)中类的实例 * 数据库表中的一行(或多行) 我们对第一个概念了解足够。 我将集中讨论第二点。 ## 从同一会话中获取的对象 从同一 Hibernate 会话再次请求持久对象**会返回类**的相同 Java 实例,这意味着您可以使用标准 Java `==`等式语法比较这些对象。 让我们看一个简单的例子: ```java public static void main(String[] args) { Session sessionOne = HibernateUtil.getSessionFactory().openSession(); sessionOne.beginTransaction(); // Create new Employee object EmployeeEntity emp = new EmployeeEntity(); emp.setFirstName("Lokesh"); emp.setLastName("Gupta"); //Save employee sessionOne.save(emp); sessionOne.getTransaction().commit(); //Get employee id Integer genEmpId = emp.getEmployeeId(); //New session where we will fetch the employee two times and compare the objects Session sessionTwo = HibernateUtil.getSessionFactory().openSession(); sessionTwo.beginTransaction(); EmployeeEntity employeeObj1 = (EmployeeEntity) sessionTwo.get(EmployeeEntity.class, genEmpId); EmployeeEntity employeeObj2 = (EmployeeEntity) sessionTwo.get(EmployeeEntity.class, genEmpId); //Checking equality System.out.println(employeeObj1 == employeeObj2); HibernateUtil.shutdown(); } Output: true ``` 您可以在上面看到,我们在`EmployeeEntity`上有两个实例,并且它们实际上都是同一个 Java 对象实例。 ## 从不同会话中获取的对象 如果您从多个会话中向**请求一个持久对象**,则 Hibernate 将为每个会话提供不同的实例,如果您比较这些对象实例,则`==`运算符将返回`false`。 让我们比较上面示例中的实例“`emp`”和“`employeeObj1`”,结果将为假; 因为两者都是在单独的会话中获取的。 ```java System.out.println(emp == employeeObj1); System.out.println(emp.equals(employeeObj1)); Output: false false ``` 因此,如果要在两个不同的会话中比较对象,则需要在 Java 持久化对象上实现`equals()`方法,无论如何,您都应该经常执行此方法。 (请不要忘记将`hashCode()`与它一起覆盖。) > **阅读更多信息**:[覆盖`hashCode()`和`equals()`方法](//howtodoinjava.com/java/related-concepts/working-with-hashcode-and-equals-methods-in-java/ "Working with hashCode and equals methods in java") Hibernate 将实际对象包装在代理中,因此请始终在内部使用设置器方法而不是实际属性进行比较。 现在,根据建议添加`equals()`方法,然后在检查`EmployeeEntity`上两个实例的相等性时查看行为更改。 ```java @Entity @Table(name = "Employee") public class EmployeeEntity implements Serializable { private static final long serialVersionUID = -1798070786993154676L; @Id @Column(name = "ID", unique = true, nullable = false) @GeneratedValue(strategy = GenerationType.SEQUENCE) private Integer employeeId; @Column(name = "FIRST_NAME", unique = false, nullable = false, length = 100) private String firstName; @Column(name = "LAST_NAME", unique = false, nullable = false, length = 100) private String lastName; @Override public boolean equals(Object o) { if (this == o) return true; if (!(o instanceof EmployeeEntity)) return false; EmployeeEntity otherEmployee = (EmployeeEntity) o; if (getEmployeeId() != null ? !getEmployeeId().equals(otherEmployee.getEmployeeId()) : otherEmployee.getEmployeeId() != null) return false; if (getFirstName() != null ? !getFirstName().equals(otherEmployee.getFirstName()) : otherEmployee.getFirstName() != null) return false; if (getLastName() != null ? !getLastName().equals(otherEmployee.getLastName()) : otherEmployee.getLastName() != null) return false; return true; } @Override public int hashCode() { int result = getEmployeeId() != null ? getEmployeeId().hashCode() : 0; result = 31 * result + (getFirstName() != null ? getFirstName().hashCode() : 0); result = 31 * result + (getLastName() != null?getLastName().hashCode() : 0); return result; } //Setters and Getters } ``` 现在,使用`equals()`方法再次检查是否相等。 (`==`将返回`false`,我们知道)。 ```java System.out.println(emp.equals(employeeObj1)); Output: true ``` 现在,两个对象在逻辑上和程序上都是相等的。 ## 项目要点 1. 从相同的 Hibernate 会话再次请求持久对象将返回类的“相同 Java 实例”。 2. 从不同的 Hibernate 会话中请求一个持久对象,将返回一个类的“不同的 Java 实例”。 3. 最佳实践是,始终在 Hiberate 实体中实现[`equals()`和`hashCode()`](//howtodoinjava.com/java/related-concepts/working-with-hashcode-and-equals-methods-in-java/ "Working with hashCode and equals methods in java")方法; 并始终仅使用`equals()`方法进行比较。 **祝您学习愉快!**