Session.update和HibernateTemplate.merge之间的Hibernate更新之间的区别

我看到了更新操作的类型:第一:

getHibernateTemplate().execute(new HibernateCallback() { public Object doInHibernate(Session session) { session.flush(); session.setCacheMode(CacheMode.IGNORE); SomeObject ss = (SomeObject) session.get(SomeObject.class, id); long next = ss.getAndIncrement(); session.update(ss); session.flush(); return null; } }); 

其次

  SomeObject ss = loadSomeObject(); long next = ss.getAndIncrement(); getHibernateTemplate.merge(ss); 

这两种方法也是一样的。 我想知道哪一个更好,更安全,为什么。 谢谢。

在第一个操作中,对象ss 附加到会话。 在第二次操作中它的分离 。 因此,如果您有附加对象,则可以使用更新。 如果你有一个分离的对象然后使用合并, 首先将对象附加到会话然后将进行更新

编辑:有关附加(持久)和分离对象的信息:

Hibernate定义并支持以下对象状态:

瞬态 – 如果一个对象刚刚使用new运算符进行实例化,并且它与Hibernate会话无关,则该对象是瞬态的。 它在数据库中没有持久表示,也没有分配标识符值。 如果应用程序不再持有引用,则垃圾收集器将销毁瞬态实例。 使用Hibernate Session使对象持久化(让Hibernate处理需要为此转换执行的SQL语句)。

持久性 – 持久性实例在数据库中具有表示forms和标识符值。 它可能刚刚被保存或加载,但是,它定义在Session的范围内。 Hibernate将检测对处于持久状态的对象所做的任何更改,并在工作单元完成时将状态与数据库同步。 当对象应该是瞬态的时,开发人员不会执行手动UPDATE语句或DELETE语句。

已分离 – 已分离的实例是一个持久的对象,但其会话已关闭。 当然,对对象的引用仍然有效,甚至可以在此状态下修改分离的实例。 可以在稍后的时间点将分离的实例重新附加到新的会话,使其(以及所有修改)再次持久化。 此function为需要用户思考的长时间运行工作单元启用编程模型。 我们称之为应用程序事务,即从用户的角度来看工作单元。

什么是API,没有任何代码示例?

 SessionFactory sf = ctx.getBean("hibernateSessionFactory",SessionFactory.class); Session session = sf.openSession(); Transaction t = session.beginTransaction(); try { Session s2 = sf.openSession(); Organization org = (Organization)s2.get(Organization.class,100624l);//1 org.setOrgName("org"); s2.close();//2 Organization org1 = (Organization)session.get(Organization.class,100624l);//3 org.setOrgName("testOrg"); org1.setOrgName("org");//a session.merge(org);//4 System.out.println(org == org1);//b t.commit(); } catch (HibernateException e) { t.rollback(); throw e; }finally{ session.close(); } 
  1. 第一个实例被加载并持久化。
  2. 该实例是分离的。
  3. 另一个实例已加载
  4. 在执行此操作时,会话中有相同对象的2个实例(org和org1) – org是分离的,org1是持久的如果我们在那里执行update()或saveOrUpdate(),我们得到以下exception:

org.hibernate.NonUniqueObjectException:具有相同标识符值的其他对象已与会话关联:[com.spring.model.Organization#100624]

一个。 我们在这里进行合并:

I.合并分离对象+持久对象的状态。

II。 如果发生冲突,合并的对象将获胜,就像在这种情况下,保存的值将是:testOrg

III。 如果我们在org1上合并,我们就会得到org。

湾 这将始终返回false,表示合并后,org仍处于DETACHED状态

我希望差异化。 现在很清楚。

简介:如果会话中有同一个对象的2个实例(一个是分离的,一个是持久的),saveOrUpdate()或update()将抛出exception

merge()不会抛出exception,但会在合并更改时保存对象。

这是对差异的一个很好的解释 。

希望有所帮助。

合并以下

合并有智慧。 它在实际合并之前有很多预检(如果需要)

  1. 如果Object是瞬态的,它只是触发INSERT查询使对象持久化(附加到会话)
  2. 如果Object被分离,则触发select查询以检查修改后是否修改了数据,触发UPDATE查询,否则只是忽略merge任务。

session.update在哪里

  1. 如果对象是瞬态的,则抛出exception。
  2. 如果Object被分离,它只是触发UPDATE查询而不管对象的数据更改。

session.merge比更新昂贵

基本区别是:

Merge()并不关心会话是持久的还是分离的…它只会更新而不考虑会话。

update()情况下,它将抛出一个exception,如org.hibernate.NonUniqueObjectException: a different object with the same identifier value was already associated with the session.

这里用一个很好的例子来解释:

http://www.java4developer.com/difference-between-update-and-merge-in-hibernate/

hibernate中的update()和merge()方法都用于将处于分离状态的对象转换为持久状态。 但没有什么区别。 让我们看看在什么情况下将使用哪种方法。 让我们举一个例子

 SessionFactory factory = cfg.buildSessionFactory(); Session session1 = factory.openSession(); Employee s1 = null; Object o = session1.get(Employee.class, new Integer(101)); s1 = (Student)o; session1.close(); s1.setSSN(97); Session session2 = factory.openSession(); Employee s2 = null; Object o1 = session2.get(Employee.class, new Integer(101)); s2 = (Student)o1; Transaction tx=session2.beginTransaction(); session2.merge(s1); SessionFactory factory = cfg.buildSessionFactory(); Session session1 = factory.openSession(); Employee s1 = null; Object o = session1.get(Employee.class, new Integer(101)); s1 = (Employee)o; session1.close(); s1.setMarks(97); Session session2 = factory.openSession(); Employee s2 = null; Object o1 = session2.get(Employee.class, new Integer(101)); s2 = (Employee)o1; Transaction tx=session2.beginTransaction(); session2.merge(s1); 

希望你很清楚……实际上,当我们将相同的对象一次又一次地加载到数据库中时,更新和合并方法将会出现,如上所述。