2017-02-15 15 views
2

Я использую Spring MVC + Hibernate + JPA в этом приложении. Мне нужно сделать следующее: обновление объекта (пользователя), который связан с отношением @manyToMany с другим объектом (задача). Вот мой код,Как избежать java.util.ConcurrentModificationException при слиянии сущностей в JPA и Hibernate

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); 

Здесь нужен добавить новую задачи к пользователю. Но когда я запускаю этот запрос, я получаю java.util.ConcurrentModificationException

Я попытался использовать Iterator вместо использования для каждого цикла. Но такой же результат. Другим способом я попытался использовать отдельный список для добавления старых и новых задач вместо того, чтобы использовать тот же список, что и выше. Но когда я звоню entityManager.merge(user); Удаляет существующее задание и повторно добавляет старые и новые задачи. Что мне нужно сделать, чтобы избежать этого исключения?

Я ценю вашу помощь, потому что я новичок в jpa.

+1

вы можете разместить всю StackTrace? –

+0

@ketanvijayvargiya Да, конечно. Вот ссылка на скопированную stacktrace [http://pastebin.com/QhZH5CHm] Спасибо за внимание. – RYJ

ответ

2

Попробуйте это изменить:

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

к этому:

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