簡體   English   中英

對多對多關聯EclipseLink的軟刪除

[英]Soft delete on many-to-many association EclipseLink

當我們僅使用Java代碼時,我想重寫EclipseLink發送的多對多關聯上的調用刪除操作(在關聯表上)。 讓我解釋一下目標。

我有3個表,一個人,一個單位和一個關聯表:PerInUnit,所以一個人可以處於多個單位中,一個單位可以包含許多人。 但是我對PeInUnit表有一定的依賴性(如果此人在特定日期不在場,則是另一個表(參與)),所以我不能(也不想)刪除記錄。 為此,我進行了軟件刪除,因此我可以保留記錄以進行一些統計。

我已經閱讀了有關Customizer和AdditionalCriteria的信息,並將它們設置為PerInUnit類。 當我創建em.remove(myPerInUnit);時,它可以完美地工作=> 發送到數據庫的sql查詢是Update PER_IN_UNIT SET STATUS='delete' WHERE id = #id; 並將指定的行作為狀態的“刪除”。 另外,當我閱讀所有記錄時,沒有狀態為“已刪除”的記錄。 但是我明確使用了PeeInUnit類。

這是代碼:

@Entity
@Table(name = "PER_IN_UNIT")
@AdditionalCriteria("this.status is null")
@Customizer(PIUCustomizer.class)
public class PerInUnit implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "GEN_SEQ_PIU")
    @SequenceGenerator(name = "GEN_SEQ_PIU", sequenceName = "SEQ_PIU", initialValue = 1, allocationSize = 1)
    @Column(name = "ID")
    private Long id;
    @ManyToOne(cascade=javax.persistence.CascadeType.PERSIST)
    @JoinColumn(name = "PER_ID")
    private Person person;
    @ManyToOne(cascade=javax.persistence.CascadeType.PERSIST)
    @JoinColumn(name = "UNI_ID")
    private Unit unit;
    @Column(name = "STATUS")
    private String status;
    //Constructor, getters, setters
}

以及PIUCustomizer的代碼:

public class PIUCustomizer implements DescriptorCustomizer {

    @Override
    public void customize(ClassDescriptor descriptor) {
    descriptor.getQueryManager().setDeleteSQLString("UPDATE PER_IN_UNIT SET STATUS = 'delete' WHERE ID = #ID");
    }
}

問題來了:當我將EclipseLink與雙向關系一起使用時,我想myUnit.getPeople.remove(currentPerson);一些指令,例如myUnit.getPeople.remove(currentPerson); (從單位“ myUnit”中刪除當前人員)。 但是EclipseLink發送了以下指令(在提交期間!):

DELETE FROM PER_IN_UNIT WHERE ((UNI_ID = ?) AND (PER_ID = ?))

而不是

Update PER_IN_UNIT SET STATUS='delete' WHERE ((UNI_ID = ?) AND (PER_ID = ?))

我期望並提出(顯然是由於依賴(FK))以下異常:

Query: DataModifyQuery(sql="DELETE FROM PER_IN_UNIT WHERE ((UNI_ID = ?) AND (PER_ID = ?))")
    at org.eclipse.persistence.internal.jpa.transaction.EntityTransactionImpl.commit(EntityTransactionImpl.java:157)
    at test.Crud.update(Crud.java:116)
    at test.Test.runTest(Test.java:96)
    at test.Test.main(Test.java:106)
Caused by: Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.5.2.v20140319-9ad6abd): org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: java.sql.SQLIntegrityConstraintViolationException: ORA-02292: integrity constraint (PEOPLE.FK_PAR_PIU) violated - child record found

其他問題(同類型),當我進行類似System.out.prinln(myUnit.getPeople())我的所有人員都位於單位“ myUnit”中,包括狀態為“刪除”的人。

是否可以在eclipseLink中更改一些代碼/指令/ Customizer / etc來更改人對PerInunit表的刪除調用,或者我必須自己進行查詢並使用它們,而不是使用功能強大的orm?

感謝您的回答,請原諒我英語不好!

晶圓廠

除非您使用PER_IN_UNIT表將Unit映射為ManyToMany的Person,否則調用myUnit.getPeople.remove(currentPerson)時不應刪除。 由於您有一個用於PER_IN_UNIT表的實體,這將是錯誤的,因為它實際上應該是Unit-> PerInUnit OneToMany映射,然后是PerInUnit-> Person ManyToOne映射。 然后,myUnit.getPeople.remove(currentPerson)調用將只是獲取PerInUnit實例並將其狀態標記為已刪除,或者取消引用它並讓JPA調用刪除,從而使用軟刪除SQL查詢。

通過對PER_IN_UNIT表使用ManyToMany映射,此映射完全獨立於PerInUnit實體映射,並且對可能緩存的實體或刪除它們所需的軟刪除一無所知。 如果您不想將PER_IN_UNIT表映射為一個實體,請參見http://www.eclipse.org/forums/index.php/t/243467/ ,其中顯示了如何為軟刪除配置ManyToMany映射。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM