2012-04-03 6 views
5

Oracle utilizzando EclipseLink:EclipseLink: Problemi con eliminazione a catena facendo aggiornamento invece

Ho un uno a molti relazione tra un padre (workflow) e bambini (stadio). Nel database ho un vincolo di cancellazione tale che cancella la fase di eliminazione del flusso di lavoro. Questo funziona bene da 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; 
    } 
} 

quando carico il workflow nome all'interno di un @Transactional (propagazione = Propagation.REQUIRED) metodo e quindi em.remove (workflow) tale oggetto,

ottengo eccezioni, come

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 

perché ho definito la colonna stages.workflow_id in modo che non sia annullabile.

Perché eclipselink sta tentando di aggiornare la tabella degli stage con ID del flusso di lavoro null, anziché eliminare semplicemente la riga dello stage?

Come posso risolvere il problema?

risposta

0

Si rimuove il flusso di lavoro, la proprietà annotation mappedBy significa che le fasi possiedono il proprio flusso di lavoro, pertanto l'implementazione JPA aggiorna le fasi per renderle conformi al modo in cui sono state mappate queste entità.

La mia ipotesi su ciò che si vuole fare è rimuovere mappedBy su Workflow.

cambiare le mappature in Fasi come questo:

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

Con i vecchi stadi (oltre al fatto che non ha funzionato) si sarebbe cancellare un flusso di lavoro e quindi eliminare tutte le altre fasi del flusso di lavoro che, se si cancellato una singola fase. Non pensare che fosse la vera intenzione.

+0

@ManyToOne non ha un attributo mappedBy – MeBigFatGuy

1

Non si dovrebbe avere JoinColumn su WorkFlow poiché si sta utilizzando un mappingBy, che è probabilmente la causa. Normalmente un JoinColumn non deve essere utilizzato su OneToMany (era consentito solo in JPA 2.0), è solo per OneToManys unidirezionale.

Altrimenti includere le classi complete e la traccia SQL della transazione. Sembra che incontri un vincolo bidirezionale e cerchi di risolverlo con una cancellazione superficiale. Hai altre relazioni tra i due?

Se si utilizza Elimina collegamento in cascata nel database, è possibile contrassegnare la relazione OneToMany con @CascadeOnDelete per evitare l'istruzione delete.

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