aratata
aratata

Reputation: 1397

How to save a foreign key in hibernate?

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?

My timesheet entity:

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

Upvotes: 2

Views: 308

Answers (1)

M A
M A

Reputation: 72854

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.

Upvotes: 1

Related Questions