Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

EclipseLink: Problems with cascade delete doing update instead

Oracle using EclipseLink:

I have a one to many relationship between a parent (workflow) and children (stage). In the database i have a delete constraint such that deletes on workflow delete stage. This works fine from 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;
    }
}

when i load the workflow by name inside a @Transactional(propagation = Propagation.REQUIRED) method and then em.remove(workflow) that object,

I get exceptions, such as

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

because I have defined the stages.workflow_id column to be not nullable.

Why is eclipselink trying to update the stages table with null workflow ids, rather than just deleting the stage row itself?

How do i fix that?

like image 341
MeBigFatGuy Avatar asked Nov 14 '22 07:11

MeBigFatGuy


1 Answers

You should not have the JoinColumn on the WorkFlow as you are using a mappedBy, that is most likely the cause. A JoinColumn should normally not be used on a OneToMany (was only allowed in JPA 2.0), it is only for unidirectional OneToManys.

Otherwise include the full classes and SQL trace of the transaction. It looks like it is encountering a bidirectional constraint, and trying to resolve it through a shallow delete. Do you have other relationships between the two?

If you are using delete cascading in the database you can mark the OneToMany relationship with @CascadeOnDelete to avoid the delete statement.

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

like image 76
James Avatar answered Nov 16 '22 04:11

James