💎一站式轻松地调用各大LLM模型接口,支持GPT4、智谱、星火、月之暗面及文生图 广告
# Hiberate 合并和刷新实体 > 原文: [https://howtodoinjava.com/hibernate/merging-and-refreshing-hibernate-entities/](https://howtodoinjava.com/hibernate/merging-and-refreshing-hibernate-entities/) 在先前的教程中,我们了解了在 Hiberate 中使用`save()`或`saveOrUpdate()`方法[**保存实体**](//howtodoinjava.com/hibernate/save-and-saveorupdate-for-saving-hibernate-entities/ "Save() and saveOrUpdate() for Saving Hibernate Entities")的知识。 从中我们了解到,在大多数情况下,您甚至都不需要那些方法,因为 hibernate 自动管理[**持久实体**](//howtodoinjava.com/hibernate/hibernate-entity-persistence-lifecycle-states/ "Hibernate Entity / Persistence LifeCycle States")上的更新。 在大多数情况下,您只需要关心瞬态对象。 在本教程中,我将讨论有关 Hiberate 会话类中存在的`refresh()`和`merge()`方法的一些想法。 ## 使用`refresh()`方法刷新 Hiberate 实体 有时,我们会遇到这样的情况:我们的应用数据库被某些外部应用/代理修改,因此您的应用中的相应 Hiberate 实体实际上与其数据库表示不同步,即具有旧数据。 在这种情况下,可以使用`session.refresh()`方法用数据库中可用的最新数据重新填充实体。 您可以在`Session`接口上使用`refresh()`方法之一来刷新持久对象的实例,如下所示: ```java public void refresh(Object object) throws HibernateException public void refresh(Object object, LockMode lockMode) throws HibernateException ``` 这些方法将从数据库重新加载对象的属性,并覆盖它们。 在现实生活中的应用中,除了上述情况之外,您不必经常使用`refresh()`方法。 我们来看一个`refresh()`方法的示例。 ```java public class RefreshEntityExample { public static void main(String[] args) { Session sessionOne = HibernateUtil.getSessionFactory().openSession(); sessionOne.beginTransaction(); //Create new Employee object EmployeeEntity emp = new EmployeeEntity(); emp.setEmployeeId(1); emp.setFirstName("Lokesh"); emp.setLastName("Gupta"); //Save employee sessionOne.save(emp); sessionOne.getTransaction().commit(); sessionOne.close(); //Verify employee's firstname System.out.println(verifyEmployeeFirstName(1, "Lokesh")); Session sessionTwo = HibernateUtil.getSessionFactory().openSession(); sessionTwo.beginTransaction(); //This emp.setFirstName("Vikas"); sessionTwo.refresh(emp); sessionTwo.getTransaction().commit(); sessionTwo.close(); System.out.println(emp.getFirstName().equals("Lokesh")); HibernateUtil.shutdown(); } private static boolean verifyEmployeeFirstName(Integer employeeId, String firstName){ Session session = HibernateUtil.getSessionFactory().openSession(); EmployeeEntity employee = (EmployeeEntity) session.load(EmployeeEntity.class, employeeId); //Verify first name boolean result = firstName.equals(employee.getFirstName()); session.close(); //Return verification result return result; } } Output: true true ``` 查看突出显示的线条上方。 * 第 15 行以“`Lokesh`”的名字保存员工 * 第 26 行设置了名字“`Vikas`”。 由于实体已分离,因此不会更新数据库。 * 第 27 行使用`refresh()`方法用数据库刷新实体。 * 第 32 行验证在实体中设置的名字是否已用“`Lokesh`”更新,因为这是数据库当前所拥有的名字。 这全部与刷新方法有关。 让我们看另一种类似的方法`merge()`。 ## 使用`merge()`方法合并 Hiberate 实体 方法`merge()`与`refresh()`的作用完全相反,即,它使用来自分离实体的值更新数据库。 刷新方法是使用最新的数据库信息更新实体。 所以基本上,两者是完全相反的。 当您希望将**分离实体再次更改为持久状态**时执行合并,并且将分离实体的更改迁移到(或覆盖)数据库。 合并操作的方法签名为: ```java Object merge(Object object) Object merge(String entityName, Object object) ``` Hibernate 官方文档对`merge()`方法给出了很好的解释: 将给定对象的状态复制到具有相同标识符的持久对象上。 如果当前没有与该会话关联的持久化实例,则将其加载。 返回持久实例。 如果给定实例未保存,请保存的副本并将其作为新的持久实例返回。 给定的实例不与会话关联。 如果关联是用`cascade="merge"`映射的,则此操作将级联到关联的实例。 因此,如果我以下面的代码为例,那么下面列出的几点对您来说应该很清楚。 ```java EmployeeEntity mergedEmpEntity = session.merge(empEntity); ``` * 当`empEntity`传递给`merge()`方法时,它是分离的实体。 * `merge()`方法将使用从`empEntity`获取的标识符信息搜索已加载的`EmployeeEntity`实例。 如果找到了这样的持久化实体,那么它将用于更新。 否则,将使用`empEntity`中存在的相同标识符信息将新的`EmployeeEntity`加载到会话中。 * 数据从`empEntity`复制到新发现/加载的实体。 * 由于新实体/发现实体是永久性的,因此从`empEntity`复制到该实体的所有数据都会自动保存到数据库中。 * 从`merge()`方法返回对该新实体的引用,并将其分配给`mergedEmpEntity`变量。 * `empEntity`仍然是独立实体。 ```java public class MergeEntityExample { public static void main(String[] args) { Session sessionOne = HibernateUtil.getSessionFactory().openSession(); sessionOne.beginTransaction(); //Create new Employee object EmployeeEntity emp = new EmployeeEntity(); emp.setEmployeeId(1); emp.setFirstName("Lokesh"); emp.setLastName("Gupta"); //Save employee sessionOne.save(emp); sessionOne.getTransaction().commit(); sessionOne.close(); //Verify employee's firstname System.out.println(verifyEmployeeFirstName(1, "Lokesh")); Session sessionTwo = HibernateUtil.getSessionFactory().openSession(); sessionTwo.beginTransaction(); //Set new first name emp.setFirstName("Vikas"); //Merge the emp object using merge() method EmployeeEntity mergedPersistentEmpEntity = (EmployeeEntity) sessionTwo.merge(emp); sessionTwo.getTransaction().commit(); sessionTwo.close(); //Verify employee's firstname again in database System.out.println(verifyEmployeeFirstName(1, "Vikas")); HibernateUtil.shutdown(); } private static boolean verifyEmployeeFirstName(Integer employeeId, String firstName){ Session session = HibernateUtil.getSessionFactory().openSession(); EmployeeEntity employee = (EmployeeEntity) session.load(EmployeeEntity.class, employeeId); //Verify first name boolean result = firstName.equals(employee.getFirstName()); session.close(); //Return verification result return result; } } Output: true true ``` 在上面的示例中,`mergedPersistentEmpEntity`是具有持久化的新实体。 因此,如果您想进行其他更改,请输入`mergedPersistentEmpEntity`实例。 本教程涵盖了 Hiberate 中的`merge()`和`refresh()`方法。 请记住,可以问以下问题:`merge()`和`refresh()`之间的差异,或`merge()`和`load()`之间的差异等。准备好在[**面试问题**](//howtodoinjava.com/java-interview-questions/ "Java Interview Questions")中遇到这些差异。 **祝您学习愉快!**