Hibernate JavaDoc指出Session.update(Object o)
如果已经有o
的持久化实例会引发异常,对吧?
If there is a persistent instance with the same identifier, an exception is thrown.
但是,以下代码在运行时不会抛出任何内容。我认为应该这样做!
Email email = new Email("andre", "girafa", "hi");
Session session = factory.openSession();
Transaction tx = session.beginTransaction();
session.save(email);
session.update(email);
session.update(email);
tx.commit();
// didn't throw... Let's try again
tx = session.beginTransaction();
session.update(email);
session.update(email);
tx.commit();
session.close();
// still nothing! :(
正如你所说,两次我尝试做多个update()
,但是Hibernate对我很轻松。
任何人都有预感为什么?
编辑它似乎只会在另一个等效对象时抛出,例如,email2
与email
具有相同的ID。我想文档有点草率。
答案 0 :(得分:8)
在SQL语言中,Hibernate中的更新不是UPDATE。 Hibernate处理SQL UPDATE 通过Session对象中的状态缓存自动。
但它仅适用于当前会话中加载的实体。此方法 session.update(object)用于将对象从另一个层附加到当前会话以跟踪,并可能在最后更新。
在你的情况下,它只是一个NOOP。如果出现这种情况,那将会非常糟糕:
Email email = new Email("andre", "girafa", "hi");
Session session = factory.openSession();
Transaction tx = session.beginTransaction();
int id = session.save(email);
Email anotherEmail = new Email("", "", "");
anotherEmail.id = id;
session.update(anotherEmail); // will throw
您可以在Hibernate reference上阅读有关更新方法语义的更多信息。
答案 1 :(得分:6)
没有错误,因为它与您正在更新的实例相同。
如果会话中存在DIFFERENT持久性实例并且您尝试更新(),则会引发错误。
答案 2 :(得分:0)
你可以试试session.flush()吗?查看是否会引发异常(有时提交可能不会刷新数据,具体取决于刷新模式)。
虽然我会说只有当对象在当前会话范围之外更新时才抛出异常,但是请说并发客户端。
答案 3 :(得分:0)
我建议您始终坚持使用EntityManager.merge
而不是Hibernate update
方法,update
令人困惑。
我发现这个article的解释很清楚,我经常参考。
与persist and save一样,更新方法是“原始”的Hibernate 在添加合并方法之前很久就存在的方法。它的 语义在几个关键点上有所不同:
- 它作用于传递的对象(其返回类型为void); update方法将传递的对象从分离的对象转变为持久的对象
州;- 如果您将其传递给瞬态实体,则此方法将引发异常。
在以下示例中,我们保存对象,然后逐出(分离)该对象 从上下文中,然后更改其名称并调用更新。注意我们 不要将更新操作的结果放在单独的变量中, 因为更新发生在人员对象本身上。基本上 我们将现有实体实例重新附加到持久性上 上下文-JPA规范不允许我们这样做。
Person person = new Person();
person.setName("John");
session.save(person);
session.evict(person);
person.setName("Mary");
session.update(person);
尝试在瞬态实例上调用update会导致 例外。以下内容将不起作用:
Person person = new Person();
person.setName("John");
session.update(person); // PersistenceException!
为了理解上面的部分,您需要了解transient
和detached
对象之间的区别。