Дублирование данных Spring Data JPA - PullRequest
0 голосов
/ 05 мая 2020

Имею следующую структуру проекта:

public class User {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @OneToMany(mappedBy = "user", fetch = FetchType.EAGER)
    private List<TaskCard> taskCards;
}

public class TaskCard {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @OneToMany(mappedBy = "taskCard", fetch = FetchType.LAZY)
    private List<Task> tasks;

    @ManyToOne(cascade = CascadeType.ALL)
    @JoinColumn(name = "user_id")
    private User user;
}

public class Task {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;  

    @ManyToOne(cascade = CascadeType.ALL)
    @JoinColumn(name = "task_card_id")
    private TaskCard taskCard;
}

А проблема заключается вот в чем. При доступе к методу контроллера задач POST для создания новой задачи я делаю следующее:

@PostMapping
public Task createTask(@CurrentUser UserPrincipal userPrincipal, @PathVariable("cardId") Long cardId, @RequestBody Task task) {
    User user = userService.findUserById(userPrincipal.getId());
    task.setTaskCard(user.getTaskCards().stream()
                         .filter(card -> card.getId().equals(cardId))
                         .findFirst()
                         .get());
    return taskService.saveTask(task);
}

Пользователь-участник - текущий пользователь. Но он просто хранит метаданные, и я беру из него идентификатор, чтобы найти его в базе данных пользователя. Здесь стоит отметить, что я ищу пользователя в базе и по нему беру карточки задач и ищу нужную карточку. После этого я присваиваю это значение новому tosk, чтобы он принадлежал этой карте. После этого сохраняю в репозиторий. Но проблема в том, что после этого для экземпляра User создается другая идентичная карточка, поэтому каждый раз, когда я добавляю задачу, я получаю еще одну копию карточек задач, которые есть у пользователя. Проблема в том, что я понятия не имею, как они туда попадают и как их спасают. В базе у меня все в порядке, данные не дублируются, но почему тогда при извлечении из базы я получаю не карточки, у которых 'user_id' равен этому пользователю, а все подряд вместе с дубликатами? Это даже непонятно звучит. Прилагаю скриншоты того, как выглядит моя база данных:

Это пользователи enter image description here

Это карточки задач

enter image description here

Это задачи

enter image description here

Как видно в базе все в порядке, дублирования нет, но вот что происходит при отладке: enter image description here

Я добавил 5 задач и в итоге получил 5 дубликатов карты, хотя должен быть только один. Как видите, вся проблема в «локальном» экземпляре пользователя, в котором хранятся дубликаты. Как это исправить?

1 Ответ

0 голосов
/ 05 мая 2020

Вы, вероятно, присоединяетесь к загрузке коллекций, и это то, что может случиться, если вы используете List в своей модели. Я предлагаю вам использовать Set вместо private Set<Task> tasks;

...