Java Hibernate更新按Session.update和HibernateTemplate.merge之间的差异

Java Hibernate更新按Session.update和HibernateTemplate.merge之间的差异,java,hibernate,Java,Hibernate,我查看了更新操作的类型: 第一: 其次 SomeObject ss = loadSomeObject(); long next = ss.getAndIncrement(); getHibernateTemplate.merge(ss); 这两种方法的作用相同。我想知道哪一个更好更安全,为什么。谢谢。在第一次操作中,对象ss被附加到会话。其中,与第二次操作一样,其已分离。因此,如果你有一个附加对象,你可以使用更新。如果您有一个分离的对象,则使用merge,它首先将对象

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

其次

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

这两种方法的作用相同。我想知道哪一个更好更安全,为什么。谢谢。

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

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

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

Transient-如果对象刚刚使用新操作符实例化,并且未与Hibernate会话关联,则该对象为Transient。它在数据库中没有持久表示,也没有分配标识符值。如果应用程序不再持有引用,则临时实例将被垃圾收集器销毁。使用Hibernate会话使对象持久化(并让Hibernate处理此转换需要执行的SQL语句)

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


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

没有任何代码示例的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();
 }
  • 加载第一个实例并使其持久化
  • 实例已分离
  • 另一个实例已加载
  • 在执行此操作时,同一对象有两个实例 在会话中(org和org1)–org是分离的,org1是持久的 如果在那里执行update()或saveOrUpdate(),则会出现以下异常:
  • org.hibernate.unUniqueObjectException:具有相同标识符值的不同对象已与会话关联:[com.spring.model.Organization#100624]

    a。我们在此进行合并,其中:

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

    二,。在发生冲突的情况下,被合并的对象获胜,就像在本例中一样,保存的值将是:testOrg

    三、 如果我们在org1上合并,我们就会得到org

    b。这将始终返回false,这意味着合并后,组织仍处于分离状态

    我希望差别现在清楚了

    摘要: 如果会话中存在同一对象的两个实例(一个分离实例和一个持久实例),则saveOrUpdate()或update()将引发异常


    merge()不会引发异常,但会在合并更改时保存对象。

    基本区别是:

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

    update()
    的情况下,它将抛出一个异常,如
    org.hibernate.unUniqueObjectException:具有相同标识符值的不同对象已与会话关联。

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

    合并执行以下操作

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

  • 若对象是暂时的,它只会触发INSERT查询,使对象持久化(附加到会话)
  • 若对象已分离,则激发select查询以检查数据是否已修改 如果修改,则激发更新查询,否则只需忽略合并任务
  • 其中为session.update

  • 如果对象是瞬态的,则引发异常
  • 若对象被分离,它只会触发更新查询,而不考虑对象的数据更改
  • session.merge比update昂贵

    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);
    

    希望您清楚…,实际上,当我们一次又一次地将同一对象加载到数据库中时,更新和合并方法将出现在图片中,如上图所示。

    可能重复谢谢。我如何知道一个对象是否附加到会话?我已经编辑了有关持久化和分离对象的答案,非常感谢。很好的解释:)。谢谢你的解释:-)
    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);