'how to solve multiple threading in jpa repository save method

i using spring data jpa to save entity.
i tried saving it in a different way here.
I am multithreaded that I run the save() method, so I noticed that some save() works but some save() doesn't.

Below is my code.

private static final Executor EXECUTOR = Executors.newFixedThreadPool(THREAD_POOL_SIZE);

/**
 * @param book
 */
@Transactional
public void multipleSave(final Book book) {
    IntStream.range(0, 2).forEach(index -> EXECUTOR.execute(() -> {
        log.info("(1) current thread name :: {}", Thread.currentThread().getName());
        Optional<Book> optional = bookJpaRepository.findById(book.getId());

        if(optional.isPresent()) {
            optional.get().update(book);
            return;
        }

        bookJpaRepository.save(book);
        log.info("(2) current thread name :: {}", Thread.currentThread().getName());
    }));
}

below error message

Exception in thread "pool-1-thread-38" org.springframework.dao.DataIntegrityViolationException: could not execute statement; SQL [n/a]; constraint [book.PRIMARY]; nested exception is org.hibernate.exception.ConstraintViolationException: could not execute statement

...java

Caused by: org.hibernate.exception.ConstraintViolationException: could not execute statement
    at  

....

Caused by: java.sql.SQLIntegrityConstraintViolationException: Duplicate entry '130' for key 'book.PRIMARY'
  • this is a key conflict when saving the entity
  • in my opinion, i confirmed that there is not data through findById, the other thread's side seems to be doing a flush to the entityManger to put the data into db, causing a collision for the key value.

so how to solve this problem..?
give me any opinioin, i will refer to it.

thanks.



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source