Issue
I have a timesheet entity that has a list of tasks. When I try to add a new task to the timesheet everything gets saved except the foreign key. Any ideas how should I avoid making a method with a custom SQL query and do the job in hibernate fashion?
@Entity
@Table(name = "timesheet")
public class Timesheet {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
private LocalDate date;
@OneToMany(
mappedBy = "timesheet",
cascade = CascadeType.ALL,
orphanRemoval = true,
fetch = FetchType.EAGER
)
@JsonManagedReference
private List<Task> tasks = new ArrayList<>();
My task:
@Entity
@Table(name = "task")
public class Task {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
private String title;
private Integer hours;
@ManyToOne
@JsonBackReference
private Timesheet timesheet;
Service impl:
@Override
public void addTask(int timesheetId, TaskVO taskVO) {
Timesheet oldTimesheet = timesheetRepository.findById(timesheetId).orElse(new Timesheet(date, tasks));
Task task = taskMapper.transformToEntity(taskVO);
taskRepository.save(task);
oldTimesheet.getTasks().add(task);
timesheetRepository.save(oldTimesheet);
}
Solution
There is a missing link from the Task
object to its owner Timesheet
. Filling this relationship should persist the foreign key column in the Task
table, otherwise the JPA persister will still view the timesheet
field as null in the Task
object:
@Override
public void addTask(int timesheetId, TaskVO taskVO) {
Timesheet oldTimesheet = timesheetRepository.findById(timesheetId).orElse(new Timesheet(date, tasks));
Task task = taskMapper.transformToEntity(taskVO);
task.setTimesheet(oldTimesheet); // need this
taskRepository.save(task);
oldTimesheet.getTasks().add(task);
timesheetRepository.save(oldTimesheet);
}
Note: I'm not sure about this, but you maybe don't need to save the task, if you are saving the timesheet at the end, since you have CascadeType.ALL
on the tasks
field.
Answered By - M A
Answer Checked By - Willingham (JavaFixing Volunteer)