2012-04-03 26 views
5

Oracle sử dụng EclipseLink:EclipseLink: Vấn đề với thác xóa làm cập nhật thay vì

Tôi có một đến nhiều mối quan hệ giữa cha mẹ (workflow) và trẻ em (giai đoạn). Trong cơ sở dữ liệu tôi có một ràng buộc xóa như vậy mà xóa trên giai đoạn xóa công việc. Điều này hoạt động tốt từ 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; 
    } 
} 

khi tôi tải các công việc theo tên bên trong một @Transactional (tuyên truyền = Propagation.REQUIRED) phương pháp và sau đó em.remove (workflow) đối tượng đó,

tôi nhận được ngoại lệ, chẳng hạn như

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 

vì tôi đã xác định cột stages.workflow_id không thể rỗng.

Tại sao eclipselink cố gắng cập nhật bảng giai đoạn bằng id luồng công việc không phải là thay vì chỉ xóa chính hàng giai đoạn?

Làm cách nào để khắc phục điều đó?

Trả lời

0

Bạn xóa luồng công việc, thuộc tính chú thích được ánh xạBy nghĩa là các giai đoạn sở hữu luồng công việc của họ, vì vậy việc triển khai JPA cập nhật các giai đoạn để làm cho chúng phù hợp với cách bạn ánh xạ các thực thể.

Đoán của tôi về những gì bạn muốn làm là xóa mappedBy trên Quy trình làm việc.

Thay đổi ánh xạ trong giai đoạn như thế này:

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

Với các giai đoạn cũ (ngoài thực tế nó đã không làm việc), bạn sẽ xóa một Workflow và do đó xóa tất cả các khâu khác trong công việc mà nếu bạn đã xóa một giai đoạn đơn lẻ. Đừng nghĩ đó là ý định thực sự.

+0

@ManyToOne không có một thuộc tính mappedBy – MeBigFatGuy

1

Bạn không nên có JoinColumn trên WorkFlow vì bạn đang sử dụng bản đồ được ánh xạ, đó có thể là nguyên nhân chính. Một JoinColumn thường không nên được sử dụng trên OneToMany (chỉ được cho phép trong JPA 2.0), nó chỉ dành cho OneToManys một chiều.

Nếu không, hãy bao gồm các lớp đầy đủ và theo dõi SQL của giao dịch. Dường như nó đang gặp phải một ràng buộc hai chiều, và cố gắng giải quyết nó thông qua một xóa cạn. Bạn có mối quan hệ khác giữa hai người không?

Nếu bạn đang sử dụng xóa tầng trong cơ sở dữ liệu, bạn có thể đánh dấu mối quan hệ OneToMany với @CascadeOnDelete để tránh tuyên bố xóa.

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

Các vấn đề liên quan