The solution

You must first analyze your requirements and decide which types of database write must be publicly supported by your API:

Note that it is quite in order not to publish any persistence methods on your entity interface, and instead create your own specialized methods instead.

In practice, entities often combine a mixture of exposing some persistence methods (for what are known as "CRUD" operations) and other specialized methods for business operations such as controlling the change of an entity's state.

Insert

If your entity API contains setter methods, then typically calling code will require an insert method to store new instances of your entity on the database:

Figure 1. Sample code calling an entity insert
@Inject
  private MyInsertableEntityDAO myInsertableEntityDAO;

  public void someCallToAnInsert() throws InformationalException {
    final MyInsertableEntity myInsertableEntity =
      myInsertableEntityDAO.newInstance();

    // set some field values on the new instance
    myInsertableEntity.setSomeField("some value");
    myInsertableEntity.setSomeOtherField("some other value");

    // ask the new entity instance to store itself on the database
    myInsertableEntity.insert();

  }

If your entity API must publish an insert method, change the entity API declaration to extend the Insertable interface:

Figure 2. Extending the Insertable interface
/**
 * This entity supports callers asking it to insert itself.
 */
public interface MyInsertableEntity extends StandardEntity,
    Insertable {

}

Note that the.insert() method (inherited from Insertable) throws InformationalException, in the case that validation errors are detected.

Modify

If your entity API contains setter methods, then typically calling code will require a.modify method to store changes on the database any changes to field values.

If modify support is required, you must decide whether your API should support:
  • an optimistic-lock modify - (common) the modify only succeeds if the version number held by the caller matches that on the database - this mechanism prevents users from over-writing each others' concurrent modifications;
  • a non-optimistic-lock modify - (less common) no version number checking is performed; or
  • both (rare).
Change the entity API declaration to extend (as appropriate):
  • OptimisticLockModifiable; and/or
  • Modifiable

e.g.:

Figure 3. Extending the OptimisticLockModifiable interface
/**
 * This entity supports callers asking it to modify itself.
 */
public interface MyModifiableEntity extends StandardEntity,
    OptimisticLockModifiable {

}

Note that database tables which store historical data (e.g. a history of state changes or other events) typically should not support modify.

Cancel

If your entity supports the concept of logical deletion, then typically calling code will require a.cancel method to logically delete an instance of your entity.

If cancel support is required, change the entity API declaration to extend LogicallyDeleteable:

Figure 4. Extending the LogicallyDeleteable interface
/**
 * This entity supports callers asking it to cancel itself.
 */
public interface MyLogicallyDeleteableEntity extends
    StandardEntity, LogicallyDeleteable {

}

Note that support for logical deletes requires support for optimistic locking.

Remove

If your entity supports the concept of physical deletion, then typically calling code will require a.remove method to physically delete an instance of your entity.

Business tables in Cúram rarely support physical deletion (favoring logical deletion instead). Technical tables (such as link tables) may support physical removal.

If remove support is required, you must decide whether your API should support:
  • an optimistic-lock remove - the remove only succeeds if the version number held by the caller matches that on the database - this mechanism prevents one user deleting data containing updates that another user has concurrently made;
  • a non-optimistic-lock remove - no version number checking is performed; or
  • both.
Change the entity API declaration to extend (as appropriate):
  • OptimisticLockRemovable; and/or
  • Removable

e.g.:

Figure 5. Extending the OptimisticLockRemovable interface
/**
 * This entity supports callers asking it to remove itself.
 */
public interface MyPhysicallyDeleteableEntity extends
    StandardEntity, OptimisticLockRemovable {

}