[JAVA] [Spring Dtata JPA] How to deal with the problem that DB change cannot be detected when you want to process API synchronously with a single thread in Spring Boot.

【Task】

When the DB is updated from outside the target of EntityManager (such as another thread or hitting the DB directly), the status of the updated record cannot be acquired.

If you get the updated TBL after updating the DB in a single thread, you can get the status. Even if you get the updated TBL after the DB is updated in another place (separate thread or hitting the DB directly), you cannot get the latest information.

For example, in the following example ...

1.Create record with saveAndFlush in a thread/update
2.Loop DB acquisition process for status monitoring in the same thread
3.Another thread/Update the corresponding record with another service etc.
4.If a DB change is detected in the loop, some processing is performed. ★ Even if you perform a DB search here, you cannot get the latest updated DB data.

[Cause]

When saveAndFlush is performed, the Entity is registered in the persistence context of EntityManager, and that Entity is cached until the thread ends according to the JPA standard specifications. Even if the DB is updated externally, EntityManager does not detect it. In other words, even if you search with the cache remaining, you can only get the DB value in the cached state.

[Countermeasure]

If you clear or detach the Entity cache directly and then perform a DB search, you can get the DB data after committing. (It seems that you can set it so that it does not have cache from the beginning, but it may be less necessary to disable the standard specification) It is necessary to execute the following processing before searching with repository etc.

	//DI EntityManager
	@PersistenceContext
	EntityManager entityManager;

	public void clearEntityCache() {
		//Detach to clear the cache as a common process()Not clear()use.
		entityManager.clear();
	}

reference:

Recommended Posts

[Spring Dtata JPA] How to deal with the problem that DB change cannot be detected when you want to process API synchronously with a single thread in Spring Boot.
You cannot change the project facet version from a dynamic web module to x.x. How to deal with
How to solve when you cannot connect to DB with a new container because the port is assigned to the existing docker container
When you want to change the wording to be displayed when making a select box from enum
Object-oriented design that can be used when you want to return a response in form format
A story that addresses the problem that REMOTE_ADDR cannot be acquired in a cluster built with Docker Swarm + Traefik (1.7).
How to solve the problem that it is not processed normally when nesting beans in Spring Batch
How to erase the process ID (PID) that cannot be erased! (Handling inoperability with Vim and Vi)
The first thing to do when you want to be happy with Heroku on GitHub with Eclipse in Java
How to solve the problem that notification cannot be requested on iOS14
When you want to notify an error somewhere when using graphql-spring-boot in Spring Boot
Code used when you want to process Json with only the standard library in Java (improved version) gson unnecessary
I want to get the information of the class that inherits the UserDetails class of the user who is logged in with Spring Boot.
How to add a classpath in Spring Boot
[rails] After option useful when you want to change the order of DB columns
A memo that I was addicted to when making batch processing with Spring Boot
A story that stumbled when deploying a web application created with Spring Boot to EC2
Code to use when you want to process Json with only standard library in Java
How to deal with SQLite3 :: BusyException that occurs when uploading a large number of images using ActiveStorage in seeds.rb etc.
How to create a Spring Boot project in IntelliJ
How to perform a specific process when the back button is pressed in Android Fragment
How to use the same Mapper class in multiple data sources with Spring Boot + MyBatis
Let's find out how to receive in Request Body with REST API of Spring Boot