JpaRepository抛出EntityNotFoundException而不是返回null

时间:2018-09-27 19:04:07

标签: spring orm spring-data-jpa dao

我正面临着这个非常不寻常的错误。 我有这个 Date currentTrueSystemDate = Calendar.getInstance().getTime(); SimpleDateFormat sdf = new SimpleDateFormat("dd-MMM-yyyy hh:mm:ss"); sdf.setTimeZone(TimeZone.getTimeZone("Asia/Kuwait")); String newConvertedDate = sdf.format(currentTrueSystemDate.getTime()); System.out.println(newConvertedDate); try { Date newConvertedDate2 = sdf.parse(newConvertedDate); System.out.println(newConvertedDate2); // Format the Date back to String here System.out.println(sdf.format(newConvertedDate2)); } catch (ParseException e) { System.out.println(e.getLocalizedMessage()); }

JpaRepository<SomeObject, Long>

它工作正常,当我尝试获取不存在的ID的SomeObject时,它仅返回null,然后我对其进行处理并进一步处理。

但是,当我引入我的应用程序的多个实例(例如2)并将它们隐藏在负载均衡器后面时。我执行此操作(作为脚本),在此操作中重复获取/创建/删除SomeObject。

当我只有一个实例时,我将运行以下脚本:检索(返回null)->创建SomeObject,删除SomeObject并重复检索(返回null)-> ...等等

一切正常,并且符合预期^

在我的多实例设置中,负载均衡器将请求交替路由到实例。 意思是,操作现在按以下顺序进行:

实例(1)检索(返回null)

实例(2)创建SomeObject

实例(1)删除SomeObject

在下一次迭代中,观察到一些奇怪的行为!

实例(2)检索(此处不是返回null,而是Spring突然引发以下异常):

public interface SomeRepository extends JpaRepository<SomeObject, Long> {
      @Query("select someObject from SomeObject someObject where someObject.id = ?1")
     public SomeObject getSomeObject(int id);
}

为了解决这个问题,我已经将头撞墙了几周了,但是我不知道为什么抛出此异常EntityNotFoundException。

该异常是正确的,我不明白为什么它不会像往常一样返回null。

UPD:

Caused by: org.springframework.orm.jpa.JpaObjectRetrievalFailureException: Unable to find somePackage.SomeObject with id 1; nested exception is javax.persistence.EntityNotFoundException: Unable to find somePackage.SomeObject with id 1
 at org.springframework.orm.jpa.EntityManagerFactoryUtils.convertJpaAccessExceptionIfPossible(EntityManagerFactoryUtils.java:389) ~[spring-orm-4.3.8.RELEASE.jar!/:4.3.8.RELEASE]
 at org.springframework.orm.jpa.vendor.HibernateJpaDialect.translateExceptionIfPossible(HibernateJpaDialect.java:246) ~[spring-orm-4.3.8.RELEASE.jar!/:4.3.8.RELEASE]
 at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.translateExceptionIfPossible(AbstractEntityManagerFactoryBean.java:488) ~[spring-orm-4.3.8.RELEASE.jar!/:4.3.8.RELEASE]
 at org.springframework.dao.support.ChainedPersistenceExceptionTranslator.translateExceptionIfPossible(ChainedPersistenceExceptionTranslator.java:59) ~[spring-tx-4.3.8.RELEASE.jar!/:4.3.8.RELEASE]
 at org.springframework.dao.support.DataAccessUtils.translateIfNecessary(DataAccessUtils.java:213) ~[spring-tx-4.3.8.RELEASE.jar!/:4.3.8.RELEASE]
 at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:147) ~[spring-tx-4.3.8.RELEASE.jar!/:4.3.8.RELEASE]
 at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) ~[spring-aop-4.3.8.RELEASE.jar!/:4.3.8.RELEASE]
 at org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodInterceptor.invoke(CrudMethodMetadataPostProcessor.java:133) ~[spring-data-jpa-1.11.3.RELEASE.jar!/:?]
 at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) ~[spring-aop-4.3.8.RELEASE.jar!/:4.3.8.RELEASE]
 at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92) ~[spring-aop-4.3.8.RELEASE.jar!/:4.3.8.RELEASE]
 at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) ~[spring-aop-4.3.8.RELEASE.jar!/:4.3.8.RELEASE]
 at org.springframework.data.repository.core.support.SurroundingTransactionDetectorMethodInterceptor.invoke(SurroundingTransactionDetectorMethodInterceptor.java:57) ~[spring-data-commons-1.13.3.RELEASE.jar!/:?]
 at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) ~[spring-aop-4.3.8.RELEASE.jar!/:4.3.8.RELEASE]
 at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:213) ~[spring-aop-4.3.8.RELEASE.jar!/:4.3.8.RELEASE]
 at com.sun.proxy.$Proxy201.getSomeObject(Unknown Source) ~[?:?]
 at mypackage.getSomeObject(MyClass.java:111) ~[]

2 个答案:

答案 0 :(得分:1)

如注释中所述,已启用二级缓存(EhCache?)。

这样的结果是,在问题的示例中,instance(2)认为它在第二次检索到来时便记住了创建请求,但随后却惊讶地在数据库中找不到匹配项。

答案 1 :(得分:0)

不是现成的完整答案,而是一些有关如何调试此类内容的说明(而且发表评论的时间太长)。

  1. 确保您具有可用的IDE正确配置的Spring Data JPA,Spring Data Commons和Spring Data ORM的源代码。

  2. 获取获得的异常的完整堆栈跟踪信息(不仅仅是发布的部分)。

  3. 基于堆栈跟踪,在代码中优雅地放置了断点。

  4. 运行不会在调试器中引发异常的简单方案。记下您击中的断点,而没有击中。

  5. 删除除最后一个击中的所有断点。在您击中的最后一个和您错过的第一个之间添加更多断点。

  6. 重复执行,直到这两个断点之间只有一个堆栈帧。

  7. 在两种情况下调试两个断点之间的其余代码,并观察差异。

  8. 回到这里,告诉我们您发现的问题或答案,可能包括指向问题和/或请求请求的链接。