Spring Data JPA: не удается найти вставленную сущность из другого потока - PullRequest
1 голос
/ 18 марта 2020

Я вставляю сущность в основной поток, затем в другом потоке пытаюсь прочитать поле (modifiedAt) этой вставленной сущности с помощью JPA-запроса с репозиторием Spring JPA.

interface SettlementRepository : JpaRepository<Settlement, Long> {

    /**
     * Fetches the state of a settlement.
     */
    @Query("SELECT s.modifiedAt FROM Settlement s WHERE s.id = :id")
    fun findModifiedAtById(id: Long): Instant
}

/* ... */

val transactionTemplate = TransactionTemplate(transactionManager)

val settlements: List<Settlement> = transactionTemplate.execute {
    amounts.map {
        settlementRepository.save(Settlement(...))
    }
}!!

val executorService = Executors.newFixedThreadPool(4)

settlements.forEach {
    executorService.execute {
        val lastModified = settlementRepository.findModifiedAtById(it.id)
        // But sometimes EmptyResultDataAccessException throws!
    }
}

Вставки выполняются в транзакции TransactionTemplate и должны быть сохранены и сброшены в базу данных (PostgreSQL), но иногда (не всегда) выдается EmptyResultDataAccessException.

Что не так с моим кодом?

Примечание. Я отключил кэш 2-го уровня в режиме гибернации.

Примечание 2. Мы используем pgpool в работе.

Stacktrace:

org.springframework.dao.EmptyResultDataAccessException: Result must not be null!                                                                                                  
at org.springframework.data.repository.core.support.MethodInvocationValidator.invoke(MethodInvocationValidator.java:102) ~[spring-data-commons-2.2.0.RELEASE.jar!/:2.2.0.RELEASE] 
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.2.0.RELEASE.jar!/:5.2.0.RELEASE]                      
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:212) ~[spring-aop-5.2.0.RELEASE.jar!/:5.2.0.RELEASE]                                       
at com.sun.proxy.$Proxy210.findModifiedAtById(Unknown Source) ~[na:na]                                                                                                            
at com.github.yns.service.settlement.SimpleSettlementService.notModified(SimpleSettlementService.kt:484) ~[classes!/:0.0.1]                                                    
at com.github.yns.service.settlement.SimpleSettlementService.access$notModified(SimpleSettlementService.kt:74) ~[classes!/:0.0.1]                                              
at com.github.yns.service.settlement.SimpleSettlementService$lockAndHandle$1.invoke(SimpleSettlementService.kt:466) ~[classes!/:0.0.1]                                         
at com.github.yns.service.settlement.SimpleSettlementService$lockAndHandle$1.invoke(SimpleSettlementService.kt:74) ~[classes!/:0.0.1]                                          
at com.github.yns.service.lock.LockKt.withLock(Lock.kt:52) ~[classes!/:0.0.1]                                                                                                  
at com.github.yns.service.lock.LockKt.withLock$default(Lock.kt:43) ~[classes!/:0.0.1]                                                                                          
at com.github.yns.service.settlement.SimpleSettlementService.lockAndHandle(SimpleSettlementService.kt:465) ~[classes!/:0.0.1]                                                  
at com.github.yns.service.settlement.SimpleSettlementService.access$lockAndHandle(SimpleSettlementService.kt:74) ~[classes!/:0.0.1]                                            
at com.github.yns.service.settlement.SimpleSettlementService$submitSettlement$1.run(SimpleSettlementService.kt:216) ~[classes!/:0.0.1]                                         
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source) ~[na:na]                                                                                           
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) ~[na:na]                                                                                          
at java.base/java.lang.Thread.run(Unknown Source) ~[na:na]                 
...