【问题标题】:EntityNotFoundException when using Hibernate使用 Hibernate 时出现 EntityNotFoundException
【发布时间】:2015-10-03 18:48:40
【问题描述】:

在我处理的一个应用程序中,我们的日志中一直存在问题很长一段时间了。我们认为我们最近已经修复了这个问题,但不幸的是它仍然存在,我已经没有关于如何修复它的想法。

问题在于,当我们的用户加载某个页面时,我们会在后台运行 JPQL / HQL 查询来检索显示所需的数据。由于某种原因,此查询有时会抱怨 EntityNotFoundException 但并非始终如一。当最近从我们正在查询的表中删除一条记录时,似乎有时会发生这种情况。据我所知,问题似乎是删除的记录仍在二级缓存中。我认为是这种情况的原因是,当这个异常被抛出时,它不会消失,直到我手动刷新 L2 缓存。

堆栈跟踪如下。在这个例子中,我们有一个名为“FeedPostTag”的实体,曾经有一个 ID 为 18858 的 FeedPostTag,但后来一些用户删除了它,然后当有人尝试重新加载他们的“feed”页面时,会显示这个 FeedPostTag,我们得到例外。

我们甚至尝试在删除此特定实体后立即以编程方式将其从缓存中逐出,但这似乎也不起作用。

javax.persistence.EntityNotFoundException:无法找到 za.co.bsg.ems.server.model.entity.social.FeedPostTag 与 id 18858 在 org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl$JpaEntityNotFoundDelegate.handleEntityNotFound(EntityManagerFactoryBuilderImpl.java:183) 在 org.hibernate.event.internal.DefaultLoadEventListener.load(DefaultLoadEventListener.java:219) 在 org.hibernate.event.internal.DefaultLoadEventListener.proxyOrLoad(DefaultLoadEventListener.java:275) 在 org.hibernate.event.internal.DefaultLoadEventListener.onLoad(DefaultLoadEventListener.java:151) 在 org.hibernate.internal.SessionImpl.fireLoad(SessionImpl.java:1070) 在 org.hibernate.internal.SessionImpl.internalLoad(SessionImpl.java:989) 在 org.hibernate.type.EntityType.resolveIdentifier(EntityType.java:716) 在 org.hibernate.type.ManyToOneType.assemble(ManyToOneType.java:282) 在 org.hibernate.cache.internal.StandardQueryCache.get(StandardQueryCache.java:204) 在 org.hibernate.loader.Loader.getResultFromQueryCache(Loader.java:2481) 在 org.hibernate.loader.Loader.listUsingQueryCache(Loader.java:2389) 在 org.hibernate.loader.Loader.list(Loader.java:2362) 在 org.hibernate.loader.hql.QueryLoader.list(QueryLoader.java:497) 在 org.hibernate.hql.internal.ast.QueryTranslatorImpl.list(QueryTranslatorImpl.java:387) 在 org.hibernate.engine.query.spi.HQLQueryPlan.performList(HQLQueryPlan.java:236) 在 org.hibernate.internal.SessionImpl.list(SessionImpl.java:1264) 在 org.hibernate.internal.QueryImpl.list(QueryImpl.java:103) 在 org.hibernate.jpa.internal.QueryImpl.list(QueryImpl.java:573) 在 org.hibernate.jpa.internal.QueryImpl.getResultList(QueryImpl.java:449)

我不确定这只是 Hibernate 中的一个错误,还是我们实际上在应用程序代码中做错了什么。任何帮助将不胜感激。

【问题讨论】:

  • 请提供hibernate实体的代码和配置?
  • @Praful Makani 不应该真正有所作为。简而言之,FeedPostTag 只是一个普通实体,其中 ManyToOne 引用了一些其他标准实体,例如FeedPost 和标签。至于配置,唯一真正值得注意的是L2缓存和通过EhCache的查询缓存都被启用了。顺便说一句,这只是发生这种情况的一个示例实体类,我们对其他实体也有同样的问题,而不仅仅是 FeedPostTag。
  • 我也遇到了同样的问题 请问你是怎么解决这个问题的?

标签: java hibernate


【解决方案1】:

根据您所写的内容,您的数据库 中似乎仍有对该记录的引用。请注意,在组装从查询缓存中收集的结果时会发生此异常,因此,与 FeedPostTag 具有 ManyToOne 关系的东西正在尝试加载不存在的记录。这不是关于 FeedPostTag 被 Hibernate 看到,而是关于与该实体有关系的不同记录,一旦需要,Hibernate 就无法加载。

org.hibernate.type.ManyToOneType.assemble(ManyToOneType.java:282) at     
org.hibernate.cache.internal.StandardQueryCache.get(StandardQueryCache.java:204) at 
org.hibernate.loader.Loader.getResultFromQueryCache(Loader.java:2481) at 

注意从查询缓存中加载结果,然后组装关系,最后出现异常。因此,与FeedPostTag 有关系的“某物”被缓存和检索。

在您的数据库中,检查引用了FeedPostTag 的表并检查哪个表引用了不存在的记录。比如:

select id from Tag where FeedPostTag_id = 18858;
select id from Feed where FeedPostTag_id = 18858;
select id from Post where FeedPostTag_id = 18858;

【讨论】:

  • 谢谢,但我确信问题不在于数据库中仍有一些东西在引用已​​删除的实体,原因有两个:(1) 外键约束将失败并且不允许首先删除和...
  • (2) 当我手动清除缓存时,这个问题就消失了。如果问题是数据库本身的孤立引用,那么清除缓存不会解决问题。我看到,当我们手动清除 L2 缓存时,我们也会手动清除查询缓存。我越看这个越确定它要么是查询缓存代码中的错误,要么是我做错了与查询缓存有关的事情。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多