【问题标题】:Need help tracking down cause of JPASystemException需要帮助追踪 JPASystemException 的原因
【发布时间】:2020-07-10 18:01:05
【问题描述】:

我正在运行一个 Spring Batch 应用程序,每批在我的 Postgresql 数据库中插入几千行。时不时地,没有明显的原因,我们得到以下异常:

org.springframework.orm.jpa.JpaSystemException: nested exception is javax.persistence.PersistenceException at ...

没有什么可以告诉我们什么 PersistenceException 是。它并不总是发生,也不会发生在同一个地方。我一直在研究导致此异常的常见原因并尝试了所有方法:

  1. 我实现了一个JPAVendorAdapter,它应该可以提供更好的错误消息(它没有)
  2. 我已验证存储库类已正确定义
  3. 我已经在本地运行它并在JPASystemException 中放置了一个断点,但是当执行到达那里时,堆栈跟踪中没有任何内容可以指出问题所在。

还有人有其他想法吗?我什至不知道要在这里显示什么代码,因为我不知道错误源自何处,是错误的配置、服务还是存储库。我真的很感激任何更多的想法!

完整的堆栈跟踪如下:

com.company.common.exception.ERDException: org.springframework.orm.jpa.JpaSystemException: 
nested exception is javax.persistence.PersistenceException 
at com.company.ingest.delegate.BaseDelegate.insertRecords(BaseDelegate.java:537) 
at com.company.ingest..delegate.Delegate.writeResult(Delegate.java:164) 
at com.company.ingest.job.AbstractBaseJob.insertReturnsRecords(AbstractBaseJob.java:678) 
at com.company.ingest.job.PerfReturnsWriter.processData(PerfReturnsWriter.java:115) 
at com.company.ingest.job.PerfReturnsWriter.write(PerfReturnsWriter.java:83) 
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
at java.lang.reflect.Method.invoke(Method.java:498) 
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:333) 
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:190) 
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157) 
at org.springframework.aop.support.DelegatingIntroductionInterceptor.doProceed(DelegatingIntroductionInterceptor.java:133) 
at org.springframework.aop.support.DelegatingIntroductionInterceptor.invoke(DelegatingIntroductionInterceptor.java:121) 
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) 
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:213) 
at com.sun.proxy.$Proxy201.write(Unknown Source) 
at org.springframework.batch.core.step.item.SimpleChunkProcessor.writeItems(SimpleChunkProcessor.java:175) 
at org.springframework.batch.core.step.item.SimpleChunkProcessor.doWrite(SimpleChunkProcessor.java:151) 
at org.springframework.batch.core.step.item.FaultTolerantChunkProcessor$3.doWithRetry(FaultTolerantChunkProcessor.java:328) 
at org.springframework.retry.support.RetryTemplate.doExecute(RetryTemplate.java:287) 
at org.springframework.retry.support.RetryTemplate.execute(RetryTemplate.java:211) 
at org.springframework.batch.core.step.item.BatchRetryTemplate.execute(BatchRetryTemplate.java:217) 
at org.springframework.batch.core.step.item.FaultTolerantChunkProcessor.write(FaultTolerantChunkProcessor.java:420) 
at org.springframework.batch.core.step.item.SimpleChunkProcessor.process(SimpleChunkProcessor.java:199) 
at org.springframework.batch.core.step.item.ChunkOrientedTasklet.execute(ChunkOrientedTasklet.java:75) 
at org.springframework.batch.core.step.tasklet.TaskletStep$ChunkTransactionCallback.doInTransaction(TaskletStep.java:406) 
at org.springframework.batch.core.step.tasklet.TaskletStep$ChunkTransactionCallback.doInTransaction(TaskletStep.java:330) 
at org.springframework.transaction.support.TransactionTemplate.execute(TransactionTemplate.java:133) 
at org.springframework.batch.core.step.tasklet.TaskletStep$2.doInChunkContext(TaskletStep.java:272) 
at org.springframework.batch.core.scope.context.StepContextRepeatCallback.doInIteration(StepContextRepeatCallback.java:81) 
at org.springframework.batch.repeat.support.RepeatTemplate.getNextResult(RepeatTemplate.java:374) 
at org.springframework.batch.repeat.support.RepeatTemplate.executeInternal(RepeatTemplate.java:215) 
at org.springframework.batch.repeat.support.RepeatTemplate.iterate(RepeatTemplate.java:144) 
at org.springframework.batch.core.step.tasklet.TaskletStep.doExecute(TaskletStep.java:257) 
at org.springframework.batch.core.step.AbstractStep.execute(AbstractStep.java:200) 
at org.springframework.batch.core.job.SimpleStepHandler.handleStep(SimpleStepHandler.java:148) 
at org.springframework.batch.core.job.flow.JobFlowExecutor.executeStep(JobFlowExecutor.java:64) 
at org.springframework.batch.core.job.flow.support.state.StepState.handle(StepState.java:67) 
at org.springframework.batch.core.job.flow.support.SimpleFlow.resume(SimpleFlow.java:169) 
at org.springframework.batch.core.job.flow.support.SimpleFlow.start(SimpleFlow.java:144) 
at org.springframework.batch.core.job.flow.FlowJob.doExecute(FlowJob.java:134) 
at org.springframework.batch.core.job.AbstractJob.execute(AbstractJob.java:306) 
at org.springframework.batch.core.launch.support.SimpleJobLauncher$1.run(SimpleJobLauncher.java:135) 
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) 
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) 
at java.lang.Thread.run(Thread.java:748) 

【问题讨论】:

  • PersistenceException真的没有内部异常吗?通常在 jpa 中,PersistenceException 下还有 2-5 个嵌套的执行。持久性异常真的没有消息还是您只是记录错误?你能显示异常的完整堆栈跟踪吗?
  • 真的没有其他异常。我现在没有堆栈跟踪,但我可以向你保证什么都没有。
  • 完整的堆栈跟踪无论如何都会有很大帮助。因为它会显示它发生在哪个班级和哪一行。不然真的没救了
  • 好的,当我拿到笔记本电脑时,我会发布它。但我知道抛出异常的那一行是 repository.save() 方法。并且所有“由”行所说的都是“由 PersistenceException 引起”。
  • @x4rf41 我已经添加了堆栈跟踪。如果有任何问题,请告知。

标签: hibernate spring-data-jpa spring-data


【解决方案1】:

问题在于您以抑制根本原因的方式错误地处理异常(或者您声明异常类以抑制传入的任何异常堆栈跟踪)。实际抛出的异常是你自己的业务异常。

您没有发布方法的内容:com.company.ingest.delegate.BaseDelegate.insertRecords(BaseDelegate.java:537) 但根据您发布的内容,我猜该方法看起来像这个:

public void insertRecords(...) {
    try {
        repository.save(...);
    } catch (Exception exception) {
        throw new com.company.common.exception.ERDException(exception.toString());
    }
}

这可以解释为什么抛出和记录的异常不包含任何有意义的信息。您捕获的异常确实包含消息本身。它包装了另一个异常(我们假设)包含根本原因。

如果我对您的方法的假设是正确的,那么假设您的异常将参数传递给超类(一直到 Throwable),那么以下更改将在下次发生错误时提供根本原因:

public void insertRecords(...) {
    try {
        repository.save(...);
    } catch (Exception exception) {
        throw new com.company.common.exception.ERDException("Unable to insert record", exception);
    }
}

【讨论】:

  • 是的,你的假设是正确的!我将包装保存方法,看看我得到了什么。我会接受你的回答,非常感谢。
  • 看来你是对的!感谢您的帮助。
  • 不管怎样,我们仍然看到这个异常。我以为我们已经摆脱了它,但它仍然出现。您还有其他想法吗?
  • 您是否进行了我建议的更改?如果是这样,那么新的堆栈跟踪会提供更多信息。如果没有我建议的更改所提供的信息,任何人都无法提供帮助。
  • 当然,我在所有地方都进行了更改。堆栈跟踪中没有其他信息。
【解决方案2】:

使用此处记录的异常方法来解决您的堆栈跟踪中异常的根本原因。

https://docs.oracle.com/cd/E17802_01/products/products/persistence/javadoc-1_0-fr/javax/persistence/PersistenceException.html

【讨论】:

  • 对不起,我不明白你在期待什么。 ExceptionTranslator 类确定我得到的异常不是因为任何已知的异常子类。
  • 我的意思是你应该根据抛出的异常做一些低级的故障排除,检查这个问题stackoverflow.com/questions/10493053/…
  • 我的意思是,如果您不针对似乎最有可能引发此类异常的数据库相关问题进行一些面向蛮力的故障排除,并且您不提供代码,那么您就没有其他选项,但根据抛出的异常进行一些低级故障排除。
猜你喜欢
  • 2021-09-30
  • 1970-01-01
  • 2018-11-06
  • 1970-01-01
  • 2012-08-29
  • 2023-01-22
  • 1970-01-01
  • 2011-12-25
  • 1970-01-01
相关资源
最近更新 更多