Jump to: navigation, search

EclipseLink/Examples/JPA/SoftDelete

< EclipseLink‎ | Examples‎ | JPA
Revision as of 11:19, 11 May 2011 by James.sutherland.oracle.com (Talk | contribs)

(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)

Some applications prefer to archive deleted objects instead of deleting them. This can be desired for auditing, or backup purposes. This is sometimes referred to as "soft" deletes, in that rows are never deleted, just marked as delete through a status column in the table.

EclipseLink supports soft deletes through two mechanisms, the [http://www.eclipse.org/eclipselink/api/2.3/org/eclipse/persistence/annotations/ AdditionalCriteria.html @AdditionalCriteria] annotation (or XML) and the DescriptorQueryManager API.

To implement soft deletes you need a status column in your table, in this example we will use STATUS. You can define an attribute in your entity to map to the status, or leave it as un-mapped if desired. If un-mapped, you will need to add a QueryKey for it to query on it through JPQL.

Next, you will need to override the delete operation for your entity to instead update the status field to 'deleted'. This can be done through using a DescriptorCustomizer and using the DescriptorQueryManager setDeleteSQLString() API.

Finally, to avoid having deleted object returned on queries, you can configure an @AdditionalCriteria to exclude the values.

Employee entity using soft deletes

@Entity
@AdditionalCriteria("this.status <> 'deleted'")
public class Employee {
  @Id
  @Column(name="EMP_ID")
  private long id;
  @Basic
  private String status; // This is optional, as a query-key could also be used.
}

Using DescriptorCustomizer to change delete to perform an update

public class MyCustomizer implements DescriptorCustomizer {
  public void customize(ClassDescriptor descriptor) {
    descriptor.getQueryManager().setDeleteSQLString("Update EMPLOYEE set STATUS = 'deleted' where EMP_ID = #EMP_ID");
    // Optionally add a query key for status.
    descriptor.addDirectQueryKey("status", "STATUS");
  }
}