Java org.hibernate.ObjectNotFoundException:不存在具有给定标识符的行
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/21186366/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
org.hibernate.ObjectNotFoundException:No row with the given identifier exists
提问by user3206615
I have had a problem since Hibernate 4.1.8 resulting in the following exception:
自 Hibernate 4.1.8 以来,我遇到了一个问题,导致以下异常:
org.hibernate.ObjectNotFoundException: No row with the given identifier exists: [test.hibernate.TestPrepravkaOsobaSAdresou$Uvazek#2]
I have a simple OneToMany association between two entities:
我在两个实体之间有一个简单的 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;
}
and a test case where I have one Ppv and two Uvazek. When I load and detach a Ppv, delete one Uvazek associated with loaded Ppv and merge Ppv I get an exception.
和一个测试用例,我有一个 Ppv 和两个 Uvazek。当我加载和分离 Ppv 时,删除一个与加载的 Ppv 关联的 Uvazek 并合并 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
During the Ppv merge, Hibernate tries to load the deleted Uvazek. Even though Uvazek is deleted, Hibernate still has information about it in
在 Ppv 合并期间,Hibernate 会尝试加载已删除的 Uvazek。即使 Uvazek 被删除,Hibernate 中仍然有关于它的信息
org.hibernate.collection.internal.AbstractPersistentCollection.storedSnapshot
on uvazek's set on the detached Ppv. In a previous version (<4.1.8) this works. In this simple example I can repair it by adding orphanRemoval=true
on uvazeks set on Ppv and instead of deleting uvazek remove it from uvazeks set on Ppv.
在 uvazek 的独立 Ppv 上。在以前的版本 (<4.1.8) 中,这是有效的。在这个简单的例子中,我可以通过添加orphanRemoval=true
在 Ppv 上设置的 uvazek来修复它,而不是删除 uvazek 从 Ppv 上设置的 uvazek 中删除它。
So my question is: Is this a Hibernate bug or my bad practice?
所以我的问题是:这是 Hibernate 错误还是我的错误做法?
回答by Angular University
The problem is that the Uvazek with id = 2 is attempted to be merged. Hibernate sees that it has a key, but it does not know if the object is dirty, so it's not clear if an SQL update should be made.
问题是尝试合并 id = 2 的 Uvazek。Hibernate 看到它有一个键,但它不知道该对象是否脏,因此不清楚是否应该进行 SQL 更新。
But because the key is 2, Hibernate knows that the object has to exist on the database, so it tries to load the object in order to compare it to the version it just received in memory, to see if the object has some pending modifications to be synchronized to the database.
但是因为键是 2,Hibernate 知道该对象必须存在于数据库中,所以它会尝试加载该对象,以便将其与刚在内存中收到的版本进行比较,以查看该对象是否有一些未决的修改同步到数据库。
But the select returns no results, so Hibernate has contradictory information: on one hand the database says the object does not exist. On the other hand, the object in memory says the object must exist with key 2. There is no way to decide which is correct, so the ObjectNotFoundException
is thrown.
但是 select 没有返回结果,所以 Hibernate 有矛盾的信息:一方面数据库说对象不存在。另一方面,内存中的对象表示该对象必须与键 2 一起存在。无法确定哪个是正确的,因此ObjectNotFoundException
抛出了 。
What happened is that before this version the code was accidentally basing itself on a bug that meanwhile got fixed, so this no longer works.
发生的事情是在这个版本之前,代码意外地基于一个同时得到修复的错误,所以这不再有效。
The best practice is to avoid clear and use it only if needed as a memory optimization, by clearing only objects that you know won't be modified or needed in the same session anymore, have a look at Is Session clear() considered harmful.
最佳做法是避免清除并仅在需要时将其用作内存优化,通过仅清除您知道在同一会话中不再修改或不再需要的对象,查看Is Session clear() 被认为是有害的。
回答by sorencito
You also need to remove the reference to Uvazek from Ppv. Otherwise Hibernate tries to restore the relation when you merge it back and fails, because you deleted the referenced Uvazek.
您还需要从 Ppv 中删除对 Uvazek 的引用。否则 Hibernate 会在您将其合并回来并失败时尝试恢复该关系,因为您删除了引用的 Uvazek。
This is also why adding orphan removal works for you.
这也是为什么添加孤儿删除对您有用的原因。
回答by Nagaraja JB
I had the same Hibernate exception.
我有同样的休眠异常。
After debugging for sometime, i realized that the issue is caused by the Orphan child records.
经过一段时间的调试,我意识到问题是由孤儿子记录引起的。
As many are complaining, when they search the record it exists. What i realized is that the issue is not because of the existence of the record but hibernate not finding it in the table, rather it is due to the Orphan child records.
The records which have reference to the non-existing parents!
正如许多人抱怨的那样,当他们搜索记录时,它就存在。我意识到问题不是因为记录的存在,而是因为休眠没有在表中找到它,而是由于孤儿记录。
参考不存在的父母的记录!
What i did is, find the Foreign Key references corresponding to the Table linked to the Bean.
我所做的是,找到与链接到 Bean 的表相对应的外键引用。
To find foreign key references in SQL developer
在 SQL developer 中查找外键引用
1.Save the below XML code into a file (fk_reference.xml)
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.Add the USER DEFINED extension to SQL Developer
2.在SQL Developer中添加USER DEFINED扩展
- Tools > Preferences
- Database > User Defined Extensions
- Click "Add Row" button
- In Type choose "EDITOR", Location - where you saved the xml file above
Click "Ok" then restart SQL Developer
3.Navigate to any table and you will be able to see an additional tab next to SQL, labelled FK References, displaying FK information.
4.Reference
http://www.oracle.com/technetwork/issue-archive/2007/07-jul/o47sql-086233.html
- How can I find which tables reference a given table in Oracle SQL Developer?
- 工具 > 首选项
- 数据库 > 用户定义的扩展
- 单击“添加行”按钮
- 在类型中选择“编辑器”,位置 - 您保存上面的 xml 文件的位置
单击“确定”,然后重新启动 SQL Developer
3.导航到任何表,您将能够在 SQL 旁边看到一个附加选项卡,标记为 FK 引用,显示 FK 信息。
4.参考
http://www.oracle.com/technetwork/issue-archive/2007/07-jul/o47sql-086233.html
- 如何在 Oracle SQL Developer 中找到哪些表引用了给定的表?
To find the Orphan records in all referred tables
在所有引用的表中查找孤立记录
select * from CHILD_TABLE where FOREIGNKEY not in (select PRIMARYKEY from PARENT_TABLE);
select * from CHILD_TABLE 其中 FOREIGNKEY 不在(从 PARENT_TABLE 中选择 PRIMARYKEY);
Delete these Orphan records, Commit the changes and restart the server if required.
删除这些孤立记录,提交更改并根据需要重新启动服务器。
This solved my exception. You may try the same.
这解决了我的异常。你也可以试试。