Как обновить зависимую сущность не потеряв ссылку на родительскую Spring Data Jpa Hibernate

Это мои энтити:

import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;

import javax.persistence.*;
import java.util.List;

@EqualsAndHashCode(callSuper = true)
@Entity
@Table(name = "users")
@Data
@NoArgsConstructor
public class User extends BaseEntity {

    @Column(name = "username")
    private String username;

    @Column(name = "first_name")
    private String firstName;

    @Column(name = "last_name")
    private String lastName;

    @Column(name = "password")
    private String password;

    @Enumerated(value = EnumType.STRING)
    @Column(name = "status")
    private UserStatus status;

    @Enumerated(value = EnumType.STRING)
    @Column(name = "role")
    private Role role;

    @Column(name = "refresh_token")
    private String refreshToken;

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

============================

import lombok.Data;
import lombok.EqualsAndHashCode;

import javax.persistence.*;

@EqualsAndHashCode(callSuper = true)
@Entity
@Table(name = "tasks")
@Data
public class Task extends BaseEntity {

    @Column(name = "title")
    private String title;

    @Column(name = "description")
    private String description;

    @Column(name = "position")
    private Long position;

    @Column(name = "status")
    @Enumerated(EnumType.STRING)
    private TaskStatus status;

    @ManyToOne
    @JoinColumn(name = "user_id")
    private User user;
}

Когда я обновляю title в классе Task, ссылка на user становится null. Я пробоваа сделать cascade = CascadeType.ALL и {CascadeType.REFRESH, CascadeType.MERGE} в классе Task и User поочереди, но это не сработало. Что можно сделать чтобы избежать потери задания юзера?

Обновление происходит так:

tasksRepository.save(task);

Ответы (1 шт):

Автор решения: Anastasiya

Ошибка (глупая) была вот в чем: таска получалась в контроллере как DTO, и мапилась без юзера:

@RequestMapping(method = {RequestMethod.POST, RequestMethod.PATCH})
    @PreAuthorize("hasRole('ADMIN')")
    public TaskOutDto createUpdateTask(@RequestBody @Valid TaskInDto task) {
        Task taskToSave = mapper.fromDto(task);
        taskToSave = taskService.save(taskToSave);
        return mapper.toDto(taskToSave);
    }

Решение было следующим - проверить, есть ли таск, и если да то не ставить ему юзера как null:

@Override
    @CacheEvict(allEntries = true)
    public Task save(Task taskToSave) {
        AtomicReference<Task> taskToReturn = new AtomicReference<>(taskToSave);

        if (taskToSave.getId() != null) {
            tasksRepository.findById(taskToSave.getId())
                    .ifPresent(task -> {
                        task.setTitle(taskToSave.getTitle());
                        task.setDescription(taskToSave.getDescription());
                        task.setPosition(taskToSave.getPosition());
                        task.setStatus(taskToSave.getStatus());

                        taskToReturn.set(task);
                    });
        }
        return tasksRepository.save(taskToReturn.get());
    }
→ Ссылка