【问题标题】:EclipseLink: Problems with cascade delete doing update insteadEclipseLink:级联删除的问题改为更新
【发布时间】:2012-04-03 02:57:03
【问题描述】:

使用 EclipseLink 的 Oracle:

我在父级(工作流程)和子级(阶段)之间存在一对多的关系。在数据库中,我有一个删除约束,以便在工作流删除阶段删除。这在 sqlplus 中运行良好。

class Workflow {
    @Override
    @OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL, mappedBy = "workflow",      targetEntity = Stage.class)
    @JoinColumn(name = "WORKFLOW_ID")
    public Set<Stage> getStages() {
        return m_stages;
    }
}

class Stage {
    @Override
    @ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL, optional = false, targetEntity = Workflow.class)
    @JoinColumn(name = "WORKFLOW_ID", nullable = false)
    public Workflow getWorkflow() {
        return m_workflow;
    }
}

当我在 @Transactional(propagation = Propagation.REQUIRED) 方法中按名称加载工作流,然后 em.remove(workflow) 该对象时,

我得到异常,例如

Error Code: 1407
Call: UPDATE STAGES SET WORKFLOW_ID = ?, FAILURE_STAGE_ID = ?, SUCCESS_STAGE_ID = ? WHERE (STAGE_ID = ?)
bind => [4 parameters bound]

Caused by: java.sql.SQLException: ORA-01407: cannot update    ("DB"."STAGES"."WORKFLOW_ID") to NULL

因为我已将stages.workflow_id 列定义为不可为空。

为什么 eclipselink 尝试使用空工作流 ID 更新阶段表,而不是仅仅删除阶段行本身?

我该如何解决?

【问题讨论】:

    标签: java jpa eclipselink cascade


    【解决方案1】:

    在使用 mappedBy 时,您不应该在 WorkFlow 上有 JoinColumn,这很可能是原因。 JoinColumn 通常不应在 OneToMany 上使用(仅在 JPA 2.0 中允许),它仅用于单向 OneToMany。

    否则,包括事务的完整类和 SQL 跟踪。看起来它遇到了双向约束,并试图通过浅删除来解决它。两人之间还有其他关系吗?

    如果您在数据库中使用删除级联,您可以使用@CascadeOnDelete 标记 OneToMany 关系以避免删除语句。

    看, http://wiki.eclipse.org/EclipseLink/Examples/JPA/DeleteCascade

    【讨论】:

      【解决方案2】:

      您删除工作流,注解属性 mappedBy 意味着阶段拥有其工作流,因此 JPA 实现会更新阶段以使它们符合您映射这些实体的方式。

      我猜你想要做的是删除工作流上的 mappedBy。

      更改阶段中的映射 像这样:

      class Stage {
          @Override
          @ManyToOne(mappedBy="stages") // supposed to be the name (in Workflow) of the persisted property here, I'm not used to annotate on the getter
          // no JoinColumn - WorkFlow has already defined the relationship
          public Workflow getWorkflow() {
              return m_workflow;
          }
      }
      

      对于旧阶段(除了它不起作用的事实),如果您删除了一个阶段,您将删除一个工作流,因此删除该工作流中的所有其他阶段。 不要以为那是真正的意图。

      【讨论】:

      • @ManyToOne 没有 mappedBy 属性
      猜你喜欢
      • 1970-01-01
      • 2021-10-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-08-25
      • 1970-01-01
      相关资源
      最近更新 更多