How to reproduce:
- Run a while loop forever in main thread 1 to query document A, log field F every 5 seconds.
- Update document A to make field F has different value
Field F still log the old value
do {
val questionnaireDocument = documentQueryService.query(
QuestionnaireDocument.DOCUMENT_MODEL_NAME,
filterSpecOf {
userSafeIdFilter()
QuestionnaireDocument.Path.Metadata.UUID.matches().value(uuid)
},
pageSpec = PageSpec.SINGLE
).entries.firstOrNull()?.loadDataServiceDocument()?.toQuestionnaireDocument()
println("Thread: ${Thread.currentThread().name} ---- ${questionnaireDocument?.questionnaireMetadata?.status}")
TimeUnit.MILLISECONDS.sleep(RETRY_DOWNLOAD_PDF_INTERVAL_MILLISECONDS)
} while (true)
Does anyone know the issue causes? I guess it should be due to cache or something
Hi @luu-far-shell,
it’s not clear from your excerpt what happens in the loadDataServiceDocument() method.
Hi @petr-high-peak, it calls DefaultDocumentRepository:getByDocumentReference
fun DocumentReference.loadDataServiceDocument(): DataServicesDocument? = documentRepository
.getByDocumentReference(this)
.orElse(null)
?.also {
// Note: "id" must be manually set
it.kernelDocument.setId(this.documentId)
}
Hi @luu-far-shell,
a) Do you have a custom repository implementation?
b) Where are transactional boundaries?
BTW, if you have this direct call of the repository, then in case you have multiple repositories, your application will mess up data. Your approach is against DS design.
Hi @petr-high-peak,
a) We don’t implement any custom repository.
b) There is no transactional boundary in this request.
~ Yes, I agree calling to repository directly in anti pattern, there must be some historical reason that we use that. I need to check with my colleague.
The reason is there is cache in first-level (session-level) that http thread which run the while / loop does not reflect any changes made to the same entity by other sessions (threads).
The workaround in my case is we clear the persistence context to make sure fresh data is fetched from the second-level (hazelcast) or further hit the DB.
entityManager.clear()
Be careful. DocumentEntity is not part of public interface and you shouldn’t use it directly. In the default repo the entity data is detached and whatever is returned by the load method is not changed after that.