我看到了更新操作的类型: 第一:
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);
这两种方法也是如此。我想知道哪一个更好,更安全,为什么。谢谢。
答案 0 :(得分:13)
在第一个操作中,对象ss 附加到会话。在第二个操作中,其分离。因此,如果您有附加对象,则可以使用更新。如果你有一个分离的对象,那么使用合并首先将对象加入会话,然后进行更新。
编辑:有关附加(持久)和分离对象的信息:
Hibernate定义并支持以下对象状态:
Transient - 如果一个对象刚刚使用new运算符进行实例化,并且它与Hibernate会话无关,则该对象是瞬态的。它在数据库中没有持久表示,并且没有分配标识符值。如果应用程序不再持有引用,则垃圾收集器将销毁瞬态实例。使用Hibernate Session使对象持久化(让Hibernate处理需要为此转换执行的SQL语句)。
持久性 - 持久性实例在数据库中具有表示形式和标识符值。它可能刚刚被保存或加载,但是,它定义在Session的范围内。 Hibernate将检测对处于持久状态的对象所做的任何更改,并在工作单元完成时将状态与数据库同步。当对象应该是瞬态的时,开发人员不会执行手动UPDATE语句或DELETE语句。
分离 - 分离的实例是一个持久的对象,但其会话已关闭。当然,对对象的引用仍然有效,甚至可以在此状态下修改分离的实例。可以在稍后的时间点将分离的实例重新附加到新的会话,使其(以及所有修改)再次持久化。此功能为需要用户思考的长时间运行工作单元启用编程模型。我们称之为应用程序事务,即从用户的角度来看工作单元。
答案 1 :(得分:7)
什么是没有任何代码示例的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.hibernate.NonUniqueObjectException:具有相同标识符值的其他对象已与会话关联:[com.spring.model.Organization#100624]
一个。我们在这里合并:
予。合并分离对象+持久对象的状态。
II。如果发生冲突,合并的对象将获胜,就像在这种情况下,保存的值将是:testOrg
III。如果我们在org1上合并,我们就会得到组织。
湾这将始终返回false,这意味着后合并,org仍然处于DETACHED状态
我希望差异化。现在很清楚。
摘要: 如果会话中有同一个对象的2个实例(一个是分离的,一个是持久的),saveOrUpdate()或update()将抛出异常
merge()不会抛出异常,但会在合并更改时保存对象。
答案 2 :(得分:3)
答案 3 :(得分:2)
遵循合并
合并有智慧。它在进行实际合并之前有很多预检(如果需要)其中session.update
session.merge比更新
贵答案 4 :(得分:1)
基本区别是:
Merge()
并不关心会话是持久的还是分离的...它只会更新而不考虑会话。
如果update()
,它会抛出类似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/
答案 5 :(得分:0)
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);
希望你很清楚......实际上,当我们一次又一次地将相同的对象加载到数据库中时,更新和合并方法将会出现,如上所述。