Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to avoid java.util.ConcurrentModificationException in entity merging in JPA and Hibernate

I'm using Spring MVC + Hibernate + JPA in this application. What I need to do is, update an entity(User) which is related with @manyToMany relationship with another entity(Task). Here is my code,

User user = baseRequest.getUser();

if (user.getTasks() != null && user.getTasks().size() > 0) {
    // Get logged user by userId
    User loggedUser = em.find(User.class, user.getUserId());

    //Get existing tasks for loggedUser
    List<Task> existingTasks = loggedUser.getTasks();

    //Get new tasks for user by request
    List<Task> tasks = user.getTasks();

    for (Task t : tasks) {
        // Look up new tasks by taskId
        task = em.find(Task.class, t.getTaskId());
        if (task != null) {
            if(!existingTasks.contains(task)){
                existingTasks.add(task);
            }
        }else{
            throw new SfaCustomException(String.format("taskId is required"));
        }
    }           
    user.setTasks(existingTasks);
}
entityManager.merge(user);
entityManager.flush();
entityManager.refresh(user);

Here I need to add new tasks to a user. But when I run this request, I'm getting java.util.ConcurrentModificationException

I tried to use Iterator instead of using for-each loop. But same result. In another way I tried using a separate List to adding old and new tasks instead of using a same list as above. But when I call entityManager.merge(user); It deletes existing task and re-add both old and new tasks. What I need to do to avoid getting this exception?

I appreciate your help, because I'm new to jpa.

like image 789
RYJ Avatar asked Feb 15 '17 17:02

RYJ


People also ask

How do you stop Java Util ConcurrentModificationException?

To Avoid ConcurrentModificationException in single-threaded environment. You can use the iterator remove() function to remove the object from underlying collection object. But in this case, you can remove the same object and not any other object from the list.

What is ConcurrentModificationException and how it can be prevented?

ConcurrentModificationException is a predefined Exception in Java, which occurs while we are using Java Collections, i.e whenever we try to modify an object concurrently without permission ConcurrentModificationException occurs which is present in java. util package.

How does ConcurrentHashMap avoid ConcurrentModificationException?

ConcurrentHashMap does not throw ConcurrentModificationException if the underlying collection is modified during an iteration is in progress. Iterators may not reflect the exact state of the collection if it is being modified concurrently. It may reflect the state when it was created and at some moment later.

What is ConcurrentModificationException what will happen if we use remove?

The ConcurrentModificationException occurs when an object is tried to be modified concurrently when it is not permissible. This exception usually comes when one is working with Java Collection classes. For Example - It is not permissible for a thread to modify a Collection when some other thread is iterating over it.


1 Answers

Try changing this:

//Get existing tasks for loggedUser
List<Task> existingTasks = loggedUser.getTasks();

to this:

//Get existing tasks for loggedUser
List<Task> existingTasks = new ArrayList<>(loggedUser.getTasks());
like image 151
Vlad Mihalcea Avatar answered Sep 25 '22 06:09

Vlad Mihalcea