Java ObjectNotFoundException:不存在具有给定标识符的行
自Hibernate 4.1.8以来,我遇到了一个问题,导致以下异常:Java ObjectNotFoundException:不存在具有给定标识符的行,java,spring,hibernate,Java,Spring,Hibernate,自Hibernate 4.1.8以来,我遇到了一个问题,导致以下异常: org.hibernate.ObjectNotFoundException: No row with the given identifier exists: [test.hibernate.TestPrepravkaOsobaSAdresou$Uvazek#2] 我在两个实体之间有一个简单的单一关联: @Entity(name = "Ppv") @Table(name = "PPV") public static cla
org.hibernate.ObjectNotFoundException: No row with the given identifier exists: [test.hibernate.TestPrepravkaOsobaSAdresou$Uvazek#2]
我在两个实体之间有一个简单的单一关联:
@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合并期间,Hibernate尝试加载已删除的Uvazek。即使删除了Uvazek,Hibernate中仍然有关于它的信息
org.hibernate.collection.internal.AbstractPersistentCollection.storedSnapshot
在分离的Ppv上设置了uvazek。在以前的版本中,问题是试图合并id为2的Uvazek。Hibernate看到它有一个键,但它不知道对象是否脏,因此不清楚是否应该进行SQL更新 但由于键为2,Hibernate知道对象必须存在于数据库中,因此它尝试加载对象,以便将其与刚在内存中收到的版本进行比较,以查看对象是否有一些待同步到数据库的未决修改 但是select没有返回结果,所以Hibernate有矛盾的信息:一方面,数据库说对象不存在。另一方面,内存中的对象表示该对象必须与键2一起存在。无法确定哪个是正确的,因此将抛出ObjectNotFoundException 发生的事情是,在此版本之前,代码意外地基于一个bug,而这个bug同时得到了修复,所以这不再有效
最好的做法是避免清除,并仅在需要时将其用作内存优化,只清除您知道在同一会话中不再修改或需要的对象 您还需要从Ppv中删除对Uvazek的引用。否则,Hibernate会在您将关系合并回来时尝试恢复该关系,但失败,因为您删除了引用的Uvazek
这也是添加孤立删除对您有效的原因 我也有同样的Hibernate异常 经过一段时间的调试,我意识到问题是由孤儿记录引起的 正如许多人抱怨的那样,当他们搜索记录时,它是存在的。 我意识到问题不是因为记录的存在,而是hibernate没有在表中找到它,而是因为孤儿记录 引用不存在的父项的记录 我所做的是,找到与链接到Bean的表对应的外键引用 在SQL developer中查找外键引用的步骤 1.将以下XML代码保存到文件fk_reference.XML中
<items>
<item type="editor" node="TableNode" vertical="true">
<title><![CDATA[FK References]]></title>
<query>
<sql>
<![CDATA[select a.owner,
a.table_name,
a.constraint_name,
a.status
from all_constraints a
where a.constraint_type = 'R'
and exists(
select 1
from all_constraints
where constraint_name=a.r_constraint_name
and constraint_type in ('P', 'U')
and table_name = :OBJECT_NAME
and owner = :OBJECT_OWNER)
order by table_name, constraint_name]]>
</sql>
</query>
</item></items>
2.将用户定义的扩展添加到SQL Developer
工具>首选项
数据库>用户定义的扩展
单击添加行按钮
在类型选择编辑器中,位置-上面保存xml文件的位置
单击“确定”,然后重新启动SQL Developer
3.导航到任何表,您将能够看到SQL旁边的附加选项卡,标记为FK引用,显示FK信息
4.参考资料
在所有引用的表中查找孤立记录
从子表中选择*
其中FOREIGNKEY不在父表中选择PRIMARYKEY
删除这些孤立记录,提交更改并在需要时重新启动服务器
这解决了我的例外。您可以尝试相同的方法。但是为什么hibernate尝试合并Uvazek?uvazeks集合上没有合并级联。是因为我尝试合并Ppv,并且在uvazeks集合上有fetch=FetchType.EAGER吗?在这种情况下,我标记Ppv后,Hibernate需要整个实体树才能持久化?这只是一个例子。我仅将clear用作客户机-服务器通信的模拟。实际上这有点复杂。一个救世主。我的表中意外地有一个空值。
<items>
<item type="editor" node="TableNode" vertical="true">
<title><![CDATA[FK References]]></title>
<query>
<sql>
<![CDATA[select a.owner,
a.table_name,
a.constraint_name,
a.status
from all_constraints a
where a.constraint_type = 'R'
and exists(
select 1
from all_constraints
where constraint_name=a.r_constraint_name
and constraint_type in ('P', 'U')
and table_name = :OBJECT_NAME
and owner = :OBJECT_OWNER)
order by table_name, constraint_name]]>
</sql>
</query>
</item></items>