I have a scenario where I have a relationship between two tables. One being the step and the other being to know who is the next step.
select * from cpo_workflow_step_control;
Step entity:
@Entity @Table(name = "cpo_workflow_step") public class CpoWorkflowStep implements java.io.Serializable { @Id @Column(name = "workflow_step_id") @OneToMany(fetch = FetchType.EAGER, mappedBy = "cpoWorkflowStepByWorkflowNextStepId", cascade = CascadeType.ALL, orphanRemoval = true) private Set<CpoWorkflowStepControl> cpoWorkflowStepControlsForWorkflowNextStepId = new HashSet<CpoWorkflowStepControl>(0); @OneToMany(fetch = FetchType.EAGER, mappedBy = "cpoWorkflowStepByWorkflowStepId", cascade = CascadeType.ALL, orphanRemoval = true) private Set<CpoWorkflowStepControl> cpoWorkflowStepControlsForWorkflowStepId = new HashSet<CpoWorkflowStepControl>(0);
Step_Control
@Entity @Table(name = "cpo_workflow_step_control") public class CpoWorkflowStepControl implements java.io.Serializable { @Id @Column(name = "workflow_step_control_id") private String workflowStepControlId; @ManyToOne(fetch = FetchType.EAGER, cascade = CascadeType.ALL) @JoinColumn(name = "workflow_next_step_id", nullable = false) private CpoWorkflowStep cpoWorkflowStepByWorkflowNextStepId; @ManyToOne(fetch = FetchType.EAGER) @JoinColumn(name = "workflow_step_id", nullable = false) private CpoWorkflowStep cpoWorkflowStepByWorkflowStepId;
My problem is, when I try to save a Step, with a Step_Control associated, JPA tries to save everything and it complains that the last object is missing some properties. Because the last Step, in the propertie cpoWorkflowStepControlsForWorkflowStepId was not save yet.
16:05:07.587 [http-nio-8004-exec-1] WARN o.h.e.jdbc.spi.SqlExceptionHelper - SQL Error: 1048, SQLState: 23000 16:05:07.587 [http-nio-8004-exec-1] ERROR o.h.e.jdbc.spi.SqlExceptionHelper - Column 'workflow_id' cannot be null
So there is a way to tell JPA what is the order to save all Steps first before to save Step_Control? Do I need to save all Steps before to save Step_Control separated?
I’m using save method from JpaRepository to save a Workflow object with all Steps and its relations inside. 1 – Workflow -> *Step -> *Step_Control
workflowRepository.save(workflowFound);
Advertisement
Answer
I think in this case is better first to save all steps, before any step control.
I would at least delete the cascade = CascadeType.ALL
from the @OneToMany
annotation. After this I would first save the steps and the with the steps saved, the step control.
The problem of the mapping you have is that step is trying to save step control, but also step control is trying to save step, the saves shall be just in one direction in order to avoid these problems.
Also I wanted to mention the you should use the fetch = FetchType.EAGER property
very carefully as it can lead you to a memory leak problem.