使用JPA绕过“实体未找到”错误

22
有时候清除一个实体的所有引用是相当困难(或者会影响性能)。例如,我有一个Person对象,它与其他Person对象存在关联关系。当我删除一个Person时,并不希望在所有可能与之相关的关系中都删除这个Person对象,因为有时这个Person对象并不知道在哪里被引用。因此,如果我想要彻底清除所有引用,就必须进行额外的SQL操作,这可能会导致性能问题。在理想的情况下,我想要删除Person对象,当另一个Person引用它时(因为在它的关系中有它的ID),只需返回null。事实上,JPA会抱怨:
javax.persistence.EntityNotFoundException: No row with the given identifier exists

在这种情况下,有没有一种方法可以强制 JPA 返回一个空引用而不是异常?

4个回答

41

您可以使用@NotFound注释,并将值设置为NotFoundAction.IGNORE,如果关联的实体不存在,则返回null。

需要注意的是:如果您在集合中使用此功能,当Hibernate找不到其中一个条目时,它会在集合中添加一个空值,这非常令人烦恼。为了避免这种情况,您可以将集合包装在一个跳过null的集合中。


这正是我在寻找的!非常感谢。这是与Hibernate相关的,不是吗? - Jerome Cance
1
很高兴能够帮到你,是的,这个注释是专门针对Hibernate的。 - Augusto
@Augusto 为什么Spring Data首先会抛出这个异常? - svlada
2
@svlada。这是因为存在外键,它没有被强制执行。因此,表A有一列存储表B的ID,但是表B中没有具有该主键的行。当外键未被强制执行时,通常会出现这种情况。因此,如果有人遇到这种情况,这意味着关系型数据库未被正确使用。 - Augusto
当我将hibernate-annotations添加到我的Java项目中时,我的war文件无法部署。无法构建Hibernate SessionFactory: <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-annotations</artifactId> <version>3.5.6-Final</version> </dependency> - TalesMGodois
这是一个Hibernate注解,在JPA中你不能这样做。 - alessandroAmedei

5

不,至少没有标准的(JPA)。

但是你可以使用cascade属性或@*ToMany@*ToOne注释来控制这些关联的发生情况。


3
你可以使用@NotFound(action=NotFoundAction.IGNORE)来跳过空实体。 但是(正如Augusto所说),如果你使用Primefaces Datatable并获取了10行数据并跳过了2行, 由于你的属性中有@NotFound(action=NotFoundAction.IGNORE),你将得到10行而不是8行(实际上是幽灵行)。
@NotFound(action=NotFoundAction.IGNORE)
private Product p;

-3
ERROR 1452: Cannot add or update a child row: a foreign key constraint fails....
   if this type of error occur :
   then
  First of all
  goto this table and check in setting > if Engine is: InnoDB then change its to MyISAM

 (and delete references foreign constraint)

它是百分之百可行的...


这个回答如何解答了楼主的问题? - John Allison

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接