Hibernate Load不从会话缓存中获取对象

时间:2013-01-25 05:52:42

标签: java hibernate session get load

我尝试了以下代码:

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的对象在会话缓存中。

现在我再次尝试为ID#5调用load()方法并调用其setter。它再次抛出ObjectNotFoundException。

问题1

为什么它无法从会话缓存中选择记录?

当我创建新对象并尝试致电saveOrUpdate()时,它会提供NonUniqueObjectException

  

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

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

问题2

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

2 个答案:

答案 0 :(得分:3)

The documentation说:

  

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

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

答案 1 :(得分:0)

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

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

应该是

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