# 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()`方法进行比较。

**祝您学习愉快！**