微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

java – org.hibernate.ObjectNotFoundException:没有给定标识符的行存在

自从Hibernate 4.1.8以来我有一个问题,导致以下异常:
org.hibernate.ObjectNotFoundException: No row with the given identifier exists: [test.hibernate.TestPrepravkaOsobaSAdresou$Uvazek#2]

我有两个实体之间的简单OnetoMany关联:

@Entity(name = "Ppv")
@Table(name = "PPV")
public static class Ppv {

  @Id
  Long ppvId;

  @OnetoMany(fetch = FetchType.EAGER,mappedBy = "ppv")
  Set<Uvazek> uvazeks = new HashSet<Uvazek>(0);
}


@Entity(name = "Uvazek")
@Table(name = "UVAZEK")
public static class Uvazek {

  @Id
  Long uvazekId;

  @ManyToOne
  @JoinColumn(name = "PPV_FXID")
  Ppv ppv;

}

一个测试用例,我有一个Ppv和两个Uvazek.当我加载和分离一个Ppv,删除一个Uvazek与加载Ppv相关联并合并Ppv我得到一个异常.

jdbcTemplate.execute("insert into PPV values(1)");
jdbcTemplate.execute("insert into UVAZEK values(2,1)");
jdbcTemplate.execute("insert into UVAZEK values(3,1)");

Ppv ppv = (Ppv) getSession().get(Ppv.class,1l);
getSession().clear();

getSession().delete(getSession().get(Uvazek.class,2l));
getSession().flush();
getSession().merge(ppv);
getSession().flush();             //Causes the exception

在Ppv合并期间,Hibernate尝试加载已删除的Uvazek.即使Uvazek被删除,Hibernate仍然有关于它的信息

org.hibernate.collection.internal.AbstractPersistentCollection.storedSnapshot

在uvazek设置在分离的Ppv.在以前的版本(<4.1.8)中,这是有效的.在这个简单的例子中,我可以通过在Ppv上设置的uvazeks上添加orphanRemoval = true来修复它,而不是删除uvazek将其从在ppv上设置的uvazeks中删除. 所以我的问题是:这是一个Hibernate错误还是我的坏习惯?

解决方法

问题是试图合并id = 2的Uvazek. Hibernate看到它有一个键,但是它不知道对象是否是脏的,所以不清楚是否应该进行sql更新.

但是由于关键是2,Hibernate知道对象必须存在于数据库上,所以它尝试加载对象,以便将其与刚刚在内存中接收到的版本进行比较,以查看对象是否有一些待处理的修改数据库同步.

但是select不会返回任何结果,所以Hibernate具有矛盾的信息:一方面数据库表示该对象不存在.另一方面,内存中的对象表示对象必须与键2一起存在.无法确定哪个对象是正确的,因此抛出ObjectNotFoundException异常.

发生了什么事情,在这个版本之前,代码意外地基于一个同时被修复的错误,所以这不再工作.

最佳做法是避免清除,只有在需要作为内存优化的情况下才可以使用它,只需清除在同一个会话中不再修改或需要的对象,再看看Is Session clear() considered harmful.

原文地址:https://www.jb51.cc/java/122605.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐