package io.ebean; import io.ebean.bean.EntityBean; /** * A MappedSuperclass base class that provides convenience methods for inserting, updating and * deleting beans. *
* By having your entity beans extend this it provides a 'Active Record' style programming model for * Ebean users. *
* Note that there is a ebean-mocker project that enables you to use Mockito or similar * tools to still mock out the underlying 'default Database' for testing purposes. *
* You may choose not use this Model mapped superclass if you don't like the 'Active Record' style * or if you believe it 'pollutes' your entity beans. *
* You can use Dependency Injection like Guice or Spring to construct and wire a Database instance * and have that same instance used with this Model and Finder. The way that works is that when the * DI container creates the Database instance it can be registered with DB. In this * way the Database instance can be injected as per normal Guice / Spring dependency injection and * that same instance also used to support the Model and Finder active record style. *
* If you choose to use the Model mapped superclass you will probably also chose to additionally add * a {@link Finder} as a public static field to complete the active record pattern and provide a * relatively nice clean way to write queries. *
*
{@code
*
* // Typically there is a common base model that has some
* // common properties like the ones below
*
* @MappedSuperclass
* public class BaseModel extends Model {
*
* @Id Long id;
*
* @Version Long version;
*
* @WhenCreated Timestamp whenCreated;
*
* @WhenUpdated Timestamp whenUpdated;
*
* ...
*
* }
* *
{@code
*
* // Extend the mappedSuperclass
*
* @Entity @Table(name="o_account")
* public class Customer extends BaseModel {
*
* String name;
* ...
* }
*
* }
* *
{@code
*
* // Active record style ... save(), delete() etc
* Customer customer = new Customer();
* customer.setName("AC234");
*
* // save() method inherited from Model
* customer.save();
*
* }
*/
public abstract class Model {
/**
* The name of the database this entity will use, null for the default database.
*/
private final String _$dbName;
/**
* Create using the default database.
*/
public Model() {
this._$dbName = null;
}
/**
* Create with a named database (typically not the default database).
*/
public Model(String dbName) {
this._$dbName = dbName;
}
/**
* Return the underlying 'default' Database.
* * This provides full access to the API such as explicit transaction demarcation etc. *
* Example: *
{@code
*
* try (Transaction transaction = Customer.db().beginTransaction()) {
*
* // turn off cascade persist for this transaction
* transaction.setPersistCascade(false);
*
* // extra control over jdbc batching for this transaction
* transaction.setBatchGetGeneratedKeys(false);
* transaction.setBatchMode(true);
* transaction.setBatchSize(20);
*
* Customer customer = new Customer();
* customer.setName("Roberto");
* customer.save();
*
* Customer otherCustomer = new Customer();
* otherCustomer.setName("Franko");
* otherCustomer.save();
*
* transaction.commit();
*
* }
*
* }
*/
public Database db() {
return DB.byName(_$dbName);
}
/**
* Marks the entity bean as dirty.
* * This is used so that when a bean that is otherwise unmodified is updated the version * property is updated. *
* An unmodified bean that is saved or updated is normally skipped and this marks the bean as * dirty so that it is not skipped. *
*
{@code
*
* Customer customer = Customer.find.byId(id);
*
* // mark the bean as dirty so that a save() or update() will
* // increment the version property
* customer.markAsDirty();
* customer.save();
*
* }
*
* @see Database#markAsDirty(Object)
*/
public void markAsDirty() {
db().markAsDirty(this);
}
/**
* Mark the property as unset or 'not loaded'.
* * This would be used to specify a property that we did not wish to include in a stateless update. *
*{@code
*
* // populate an entity bean from JSON or whatever
* User user = ...;
*
* // mark the email property as 'unset' so that it is not
* // included in a 'stateless update'
* user.markPropertyUnset("email");
*
* user.update();
*
* }
*
* @param propertyName the name of the property on the bean to be marked as 'unset'
*/
public void markPropertyUnset(String propertyName) {
((EntityBean) this)._ebean_getIntercept().setPropertyLoaded(propertyName, false);
}
/**
* Insert or update this entity depending on its state.
* * Ebean will detect if this is a new bean or a previously fetched bean and perform either an * insert or an update based on that. * * @see Database#save(Object) */ public void save() { db().save(this); } /** * Flush any batched changes to the database. *
* When using JDBC batch flushing occurs automatically at commit() time or when the batch size * is reached. This provides the ability to manually flush the batch. *
*/ public void flush() { db().flush(); } /** * Update this entity. * * @see Database#update(Object) */ public void update() { db().update(this); } /** * Insert this entity. * * @see Database#insert(Object) */ public void insert() { db().insert(this); } /** * Delete this bean. ** This will return true if the bean was deleted successfully or JDBC batch is being used. *
** If there is no current transaction one will be created and committed for * you automatically. *
** If the Bean does not have a version property (or loaded version property) and * the bean does not exist then this returns false indicating that nothing was * deleted. Note that, if JDBC batch mode is used then this always returns true. *
* * @see Database#delete(Object) */ public boolean delete() { return db().delete(this); } /** * Delete a bean permanently without soft delete. *
* This is used when the bean contains a @SoftDelete property and we
* want to perform a hard/permanent delete.
*