如何使用JPA解决javax.persistence.EntityNotFoundException(而不是通过使用@NotFound)

2022-09-02 10:52:03

我们正在使用JPA从数据库中加载一些东西。某些实体之间可能有可选的关系,例如

@Entity
public class First {
    ....
    @OneToOne(cascade = {CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REFRESH, CascadeType.DETACH})
    @JoinColumns(value = {
        JoinColumn(name = "A_ID", referencedColumnName = "A_ID", insertable = false, updatable = false), 
        JoinColumn(name = "B_ID", referencedColumnName = "B_ID", insertable = false, updatable = false)})
    private Second second;

当数据库中存在此关联时,一切正常。如果不是,则我得到的是我想要
的,而不是异常,如果关联不存在,则将此字段设置为NULL。javax.persistence.EntityNotFoundException

我已经尝试了几种不同的方法,例如在关系注释中使用anfety=true(顺便说一句,这是默认选项),将其设置为Nullable等。似乎没有什么可以解决问题,似乎所有这些选项都被忽略了。

我发现很多链接都提到了同样的问题(stackoverflow中的一些问题),但在所有这些链接中,建议使用Hibernate的注释。但是我们不希望对Hibernate有任何依赖性(我们希望保持所有纯JPA)。@NotFound

你们有谁知道其他方法来解决这个问题吗?

非常感谢您的帮助!


答案 1

以下是此问题的替代解决方案。我不得不在一个旧数据库的基础上进行构建,那里的关系有时会损坏。这就是我仅使用JPA来解决它的方法。

@PostLoad
public void postLoad(){
    try {
        if(getObject() != null && getObject().getId() == 0){
            setObject(null);
        }
    }
    catch (EntityNotFoundException e){
        setObject(null);
    }
} 

答案 2

我遇到了同样的问题。它并不总是可重复的,所以我无法测试它,但这里有一些想法:

  1. 第二类的实例将被删除,而第一类的实例对此一无所知。
  2. 您需要一种方法来让 First 的实例知道,当它的 Second 实例被删除时。
  3. 用于删除的级联选项在这里没有帮助。
  4. 您可以尝试使用双向关系,当第一个实例存在于第二个实例中时。它允许您在删除第二个之前通过第二个实例更新第一个实例
  5. 双向关系 - 是邪恶的。我想在你的情况下,第一 - 是第二的所有者。不允许任何服务直接删除第二个实例。让与 First 的实例一起使用的服务删除 Second 的实例。在这种情况下,您可以先使“second”字段为空,而不是通过EntityManager删除Second的实例。
  6. 当执行查询并且启用了第二级缓存并且查询具有提示(允许缓存其结果)时,您可能会遇到异常。我会通过以下方法为您提供查询结果:
private List<?> getQueryResult(final Query query)
{
    try
    {
        return query.getResultList();
    }
    catch (EntityNotFoundException e)
    {
        return query.setHint("javax.persistence.cache.storeMode", CacheStoreMode.REFRESH).getResultList();
    }
}
  1. 如果通过 EntityManger 处理实体,但不通过查询处理实体,并且由于实体已缓存而获得异常,则在删除 Second 时,可能会使缓存中 First 的所有实体失效。

我想讨论这个解决方案,因为我无法测试它,也无法使它工作。如果有人尝试,请告诉我。

PS:如果有人有一个休眠的单元测试,重现了这个问题,你能不能让我知道。我希望进一步调查它。


推荐