1

我尝试了以下代码:

Student s1 = (Student) s.load(Student.class, 5); // this records not there in DB
 try {
    s1.setName("Kaushik1");
} catch (ObjectNotFoundException e) {
    s1 = new Student();
    s1.setId(5);
    s1.setName("trying1");
}
s.saveOrUpdate(s1);

Student s2 = (Student) s.load(Student.class, 5);
try {
    s2.setName("Kaushik2");
} catch (ObjectNotFoundException e) {
    //Why should it throw ObjectNotFoundException now
    s2 = new Student();
    s2.setId(5);
    s2.setName("trying2");
}
s.saveOrUpdate(s2); //Why it throws NonUniqueObjectException

我曾经load从 ID#5 的数据库中获取记录。记录不存在。然后我尝试在对象上调用 setter,它抛出了一个异常。同意!!

由于记录不存在,我创建了一个新对象并调用saveOrUpdate(). 所以现在我假设 ID#5 的对象在会话缓存中。

现在我再次尝试调用load()ID#5 的方法并调用它的设置器。它再次抛出 ObjectNotFoundException。

问题 1

为什么它不能从 Session 缓存中选择记录?

当我创建新对象并尝试调用saveOrUpdate()它时 NonUniqueObjectException

org.hibernate.NonUniqueObjectException:具有相同标识符值的不同对象已与会话关联:[com.cts.closr.Student#5]

它抛出了 ObjectNotFoundException,现在说“对象已与会话关联”。这不矛盾吗?

问题2

这是否意味着load()方法永远不会检查会话上下文?它总是从数据库中获取?那么在这种情况下我必须使用get() 方法吗?

4

2 回答 2

4

文档说:

如果 Session 抛出异常,包括任何 SQLException,立即回滚数据库事务,调用 Session.close() 并丢弃 Session 实例。Session 的某些方法不会使会话保持一致状态。Hibernate 抛出的任何异常都不能被视为可恢复的。

因此,使用Session.load()、捕获异常并继续使用会话是一个很大的禁忌。Session.load()当您认为该对象必须存在于数据库中时必须使用,如果不存在则必须抛出异常。如果您不确定该对象是否存在,请使用Session.get(),测试返回的对象是否为空,并采取相应措施。

于 2013-01-26T08:09:37.563 回答
0

“现在我再次尝试为 ID#5 调用 load() 方法”,我相信你打错了。

    Student s2 = (Student)s.load(Student.class, 6); 

应该是

    Student s2 = (Student)s.load(Student.class, 5);

?

于 2013-01-25T06:05:17.093 回答