【发布时间】:2019-03-03 18:10:15
【问题描述】:
我正面临这个非常不寻常的错误。
我有这个JpaRepository<SomeObject, Long>
public interface SomeRepository extends JpaRepository<SomeObject, Long> {
@Query("select someObject from SomeObject someObject where someObject.id = ?1")
public SomeObject getSomeObject(int id);
}
它工作正常,当我尝试获取 ID 不存在的 SomeObject 时,它只是返回 null 并且我处理它并继续进行。
但是,当我引入了我的应用程序的多个实例(例如 2 个)并将它们隐藏在负载均衡器后面时。我执行此操作(作为脚本),它会在其中重复检索/创建/删除 SomeObject。
当我只有一个实例时,我运行以下脚本:检索(返回 null)-> 创建 SomeObject,删除 SomeObject 并重复检索(返回 null)-> ...等
一切正常,如预期的那样^
在我的多实例设置中,负载均衡器可互换地将请求重新路由到实例。 意思是,操作现在按以下顺序发生:
实例(1)检索(返回null)
实例(2)SomeObject的创建
实例(1)删除SomeObject
在下一次迭代中,观察到一些奇怪的行为!
Instance(2)检索(这里不是返回null,Spring一下子抛出如下异常):
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) ~[]
几周以来我一直在努力解决这个问题,但我不知道为什么会抛出这个异常 EntityNotFoundException。
异常是正确的,我不明白为什么它不像往常一样返回null。
更新:
public class SomeObject {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
}
【问题讨论】:
-
你能详细说明一下
SomeObject吗?是否从中引用了其他实体? -
不,是超级简单的Entity,更新了
-
是否启用了二级缓存(例如 EhCache)?这可能导致 instance(2) 认为它知道 SomeObject,然后在查看数据库时感到惊讶。
-
@df778899 实际上我做到了,当我关闭它时,它工作正常。但这并没有真正的意义......你能添加你的答案,所以我可以给它+50分吗?
-
那里有答案 - 随时使用您知道的任何其他内容进行编辑。如果缓存性能很重要,那么可能值得研究像 Terracotta 这样的共享缓存。前段时间的经验是,性能非常好,但这绝对是设置中另一个动人的部分。
标签: spring orm spring-data-jpa dao