繁体   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