简体   繁体   English

对多对多关联EclipseLink的软删除

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

I want to rewrite the call delete operation (on association table) on a many-to-many association sending by EclipseLink when we use only java code. 当我们仅使用Java代码时,我想重写EclipseLink发送的多对多关联上的调用删除操作(在关联表上)。 Let me explain the goal. 让我解释一下目标。

I have 3 tables, person, unit and an associative one : PerInUnit, so a person can be in multiple units and a units can contains many people. 我有3个表,一个人,一个单位和一个关联表:PerInUnit,所以一个人可以处于多个单位中,一个单位可以包含许多人。 But I have some dependances on the PeInUnit table (If the person was present or not on a specific date, another table (Participations)), so I can't (and I don't want) delete a record. 但是我对PeInUnit表有一定的依赖性(如果此人在特定日期不在场,则是另一个表(参与)),所以我不能(也不想)删除记录。 For that, I make softs deletes, so I can keep records to make some statistics. 为此,我进行了软件删除,因此我可以保留记录以进行一些统计。

I read already about the Customizer and AdditionalCriteria and I setted them to the PerInUnit class. 我已经阅读了有关Customizer和AdditionalCriteria的信息,并将它们设置为PerInUnit类。 It works perfectly => when I make an em.remove(myPerInUnit); 当我创建em.remove(myPerInUnit);时,它可以完美地工作=> the sql query sent to the db is Update PER_IN_UNIT SET STATUS='delete' WHERE id = #id; 发送到数据库的sql查询是Update PER_IN_UNIT SET STATUS='delete' WHERE id = #id; and the specified row as "delete" for status. 并将指定的行作为状态的“删除”。 Also, when I read all records, I don't have them with status "delete". 另外,当我阅读所有记录时,没有状态为“已删除”的记录。 But I use explicitly the PeeInUnit class. 但是我明确使用了PeeInUnit类。

Here is the code : 这是代码:

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

And the code for the PIUCustomizer : 以及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");
    }
}

Here come the problem : As I use EclipseLink with bidirectionnal relationship I want to make some instruction like myUnit.getPeople.remove(currentPerson); 问题来了:当我将EclipseLink与双向关系一起使用时,我想myUnit.getPeople.remove(currentPerson);一些指令,例如myUnit.getPeople.remove(currentPerson); (remove the current person from the unit "myUnit"). (从单位“ myUnit”中删除当前人员)。 But EclipseLink sent the following instruction (during commit !) : 但是EclipseLink发送了以下指令(在提交期间!):

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

instead of the 而不是

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

that I expected and raise (obviously, because of dependances (FKs)) the following exception : 我期望并提出(显然是由于依赖(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

Other problem (in the same kind), when I make something like System.out.prinln(myUnit.getPeople()) I have all the people in the unit "myUnit", including them having status 'delete'. 其他问题(同类型),当我进行类似System.out.prinln(myUnit.getPeople())我的所有人员都位于单位“ myUnit”中,包括状态为“删除”的人。

Is it possible to change some code/instructions/Customizer/etc in eclipseLink to change the delete call from person for PerInunit table, or I have to make my own queries and use them instead of using powerful of orm ? 是否可以在eclipseLink中更改一些代码/指令/ Customizer / etc来更改人对PerInunit表的删除调用,或者我必须自己进行查询并使用它们,而不是使用功能强大的orm?

Thanks for your answers and please forgive me for my poor english ! 感谢您的回答,请原谅我英语不好!

Fab 晶圆厂

You should not be getting a delete when you call myUnit.getPeople.remove(currentPerson) unless you mapped Unit to Person with a ManyToMany using the PER_IN_UNIT table. 除非您使用PER_IN_UNIT表将Unit映射为ManyToMany的Person,否则调用myUnit.getPeople.remove(currentPerson)时不应删除。 Since you have an entity for the PER_IN_UNIT table, this would be wrong, as it really should be a Unit-> PerInUnit OneToMany mapping and then a PerInUnit -> Person ManyToOne mapping. 由于您有一个用于PER_IN_UNIT表的实体,这将是错误的,因为它实际上应该是Unit-> PerInUnit OneToMany映射,然后是PerInUnit-> Person ManyToOne映射。 The myUnit.getPeople.remove(currentPerson) call would then simply be getting the PerInUnit instance and marking its status as deleted, or dereferencing it and letting JPA call remove, thereby using your soft delete SQL query. 然后,myUnit.getPeople.remove(currentPerson)调用将只是获取PerInUnit实例并将其状态标记为已删除,或者取消引用它并让JPA调用删除,从而使用软删除SQL查询。

By using a ManyToMany mapping for the PER_IN_UNIT table, this mapping is completely independent to your PerInUnit entity mapping, and knows nothing about the entities that maybe cached or the soft deletes required to remove them. 通过对PER_IN_UNIT表使用ManyToMany映射,此映射完全独立于PerInUnit实体映射,并且对可能缓存的实体或删除它们所需的软删除一无所知。 If you don't want to map the PER_IN_UNIT table as an entity, see http://www.eclipse.org/forums/index.php/t/243467/ which shows how to configure a ManyToMany mapping for soft deletes. 如果您不想将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