同一实体的两个双向关联 - 列不能为空

Two bidirectional association at the same entity - Column cannot be null

我有一个场景,我在两个表之间建立了关系。一个是步骤,另一个是知道下一步是谁。

select * 来自 cpo_workflow_step_control;

步骤实体:

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

我的问题是,当我尝试保存关联了 Step_Control 的步骤时,JPA 会尝试保存所有内容,但它会抱怨最后一个对象缺少某些属性。因为最后一步,属性中的 cpoWorkflowStepControlsForWorkflowStepId 还没有保存。

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

所以有一种方法可以告诉 JPA 在保存之前先保存所有步骤的顺序是什么 Step_Control?我需要先保存所有步骤才能保存 Step_Control 分开吗?

我正在使用 JpaRepository 中的保存方法来保存一个包含所有步骤及其关系的工作流对象。 1 - 工作流程 -> *步骤 -> *Step_Control

workflowRepository.save(workflowFound);

我认为在这种情况下最好先保存所有步骤,然后再进行任何步骤控制。

我至少会从 @OneToMany 注释中删除 cascade = CascadeType.ALL。之后我会先保存步骤,保存步骤后,步骤控制。

你的映射问题是step试图保存step control,而且step control也试图保存step,保存应该只在一个方向以避免这些问题。

我还想提一下,您应该非常小心地使用 fetch = FetchType.EAGER property,因为它可能会导致内存泄漏问题。