All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.avaje.ebean.Ebean Maven / Gradle / Ivy

The newest version!
package com.avaje.ebean;

import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.logging.Logger;

import javax.persistence.OptimisticLockException;
import javax.persistence.PersistenceException;

import com.avaje.ebean.annotation.CacheStrategy;
import com.avaje.ebean.cache.ServerCacheManager;
import com.avaje.ebean.config.GlobalProperties;
import com.avaje.ebean.config.ServerConfig;
import com.avaje.ebean.text.csv.CsvReader;
import com.avaje.ebean.text.json.JsonContext;

/**
 * This Ebean object is effectively a singleton that holds a map of registered
 * {@link EbeanServer}s. It additionally provides a convenient way to use the
 * 'default/primary' EbeanServer.
 * 

* If you are using a Dependency Injection framework such as * Spring or Guice you will probably * NOT use this Ebean singleton object. Instead you will * configure and construct EbeanServer instances using {@link ServerConfig} and * {@link EbeanServerFactory} and inject those EbeanServer instances into your * data access objects. *

*

* In documentation "Ebean singleton" refers to this object. *

*
    *
  • There is one EbeanServer per Database (javax.sql.DataSource).
  • *
  • EbeanServers can be 'registered' with the Ebean singleton (put into its * map). Registered EbeanServer's can later be retrieved via * {@link #getServer(String)}.
  • *
  • One EbeanServer can be referred to as the 'default' EbeanServer. For * convenience, the Ebean singleton (this object) provides methods such as * {@link #find(Class)} that proxy through to the 'default' EbeanServer. This * can be useful for applications that use a single database.
  • *
* *

* For developer convenience Ebean has static methods that proxy through to the * methods on the 'default' EbeanServer. These methods are provided for * developers who are mostly using a single database. Many developers will be * able to use the methods on Ebean rather than get a EbeanServer. *

*

* EbeanServers can be created and used without ever needing or using the Ebean * singleton. Refer to {@link ServerConfig#setRegister(boolean)}. *

*

* You can either programmatically create/register EbeanServers via * {@link EbeanServerFactory} or they can automatically be created and * registered when you first use the Ebean singleton. When EbeanServers are * created automatically they are configured using information in the * ebean.properties file. *

* *
 * // fetch shipped orders (and also their customer)
 * List<Order> list = Ebean.find(Order.class)
 * 	.fetch("customer")
 * 	.where() 
 * 	.eq("status.code", Order.Status.SHIPPED) 
 * 	.findList();
 * 
 * // read/use the order list ... 
 * for (Order order : list) { 
 * 	Customer customer = order.getCustomer(); 
 * 	... 
 * }
 * 
* *
 * // fetch order 10, modify and save 
 * Order order = Ebean.find(Order.class, 10);
 * 
 * OrderStatus shipped = Ebean.getReference(OrderStatus.class,"SHIPPED"); 
 * order.setStatus(shipped);
 * order.setShippedDate(shippedDate); 
 * ...
 * 
 * // implicitly creates a transaction and commits 
 * Ebean.save(order);
 * 
* *

* When you have multiple databases and need access to a specific one the * {@link #getServer(String)} method provides access to the EbeanServer for that * specific database. *

* *
 * // Get access to the Human Resources EbeanServer/Database
 * EbeanServer hrDb = Ebean.getServer("hr");
 * 
 * 
 * // fetch contact 3 from the HR database 
 * Contact contact = hrDb.find(Contact.class, 3);
 * 
 * contact.setName("I'm going to change"); 
 * ...
 * 
 * // save the contact back to the HR database 
 * hrDb.save(contact);
 * 
*/ public final class Ebean { private static final Logger logger = Logger.getLogger(Ebean.class.getName()); /** * Manages creation and cache of EbeanServers. */ private static final Ebean.ServerManager serverMgr = new Ebean.ServerManager(); /** * Helper class for managing fast and safe access and creation of * EbeanServers. */ private static final class ServerManager { /** * Cache for fast concurrent read access. */ private final ConcurrentHashMap concMap = new ConcurrentHashMap(); /** * Cache for synchronized read, creation and put. Protected by the monitor * object. */ private final HashMap syncMap = new HashMap(); private final Object monitor = new Object(); /** * The 'default/primary' EbeanServer. */ private EbeanServer primaryServer; private ServerManager() { // skipDefaultServer is set by EbeanServerFactory // ... when it is creating the primaryServer if (GlobalProperties.isSkipPrimaryServer()) { // primary server being created by EbeanServerFactory // ... so we should not try and create it here logger.fine("GlobalProperties.isSkipPrimaryServer()"); } else { // look to see if there is a default server defined String primaryName = getPrimaryServerName(); logger.fine("primaryName:" + primaryName); if (primaryName != null && primaryName.trim().length() > 0) { primaryServer = getWithCreate(primaryName.trim()); } } } private String getPrimaryServerName() { String serverName = GlobalProperties.get("ebean.default.datasource", null); return GlobalProperties.get("datasource.default", serverName); } private EbeanServer getPrimaryServer() { if (primaryServer == null) { String msg = "The default EbeanServer has not been defined?"; msg += " This is normally set via the ebean.datasource.default property."; msg += " Otherwise it should be registered programatically via registerServer()"; throw new PersistenceException(msg); } return primaryServer; } private EbeanServer get(String name) { if (name == null || name.length() == 0) { return primaryServer; } // non-synchronized read EbeanServer server = concMap.get(name); if (server != null) { return server; } // synchronized read, create and put return getWithCreate(name); } /** * Synchronized read, create and put of EbeanServers. */ private EbeanServer getWithCreate(String name) { synchronized (monitor) { EbeanServer server = syncMap.get(name); if (server == null) { // register when creating server this way server = EbeanServerFactory.create(name); register(server, false); } return server; } } /** * Register a server so we can get it by its name. */ private void register(EbeanServer server, boolean isPrimaryServer) { synchronized (monitor) { concMap.put(server.getName(), server); EbeanServer existingServer = syncMap.put(server.getName(), server); if (existingServer != null) { String msg = "Existing EbeanServer [" + server.getName() + "] is being replaced?"; logger.warning(msg); } if (isPrimaryServer) { primaryServer = server; } } } } private Ebean() { } /** * Get the EbeanServer for a given DataSource. If name is null this will * return the 'default' EbeanServer. *

* This is provided to access EbeanServer for databases other than the * 'default' database. EbeanServer also provides more control over * transactions and the ability to use transactions created externally to * Ebean. *

* *
   * // use the "hr" database
   * EbeanServer hrDatabase = Ebean.getServer("hr");
   * 
   * Person person = hrDatabase.find(Person.class, 10);
   * 
* * @param name * the name of the server, use null for the 'default server' */ public static EbeanServer getServer(String name) { return serverMgr.get(name); } /** * Return the ExpressionFactory from the default server. *

* The ExpressionFactory is used internally by the query and ExpressionList to * build the WHERE and HAVING clauses. Alternatively you can use the * ExpressionFactory directly to create expressions to add to the query where * clause. *

*

* Alternatively you can use the {@link Expr} as a shortcut to the * ExpressionFactory of the 'Default' EbeanServer. *

*

* You generally need to the an ExpressionFactory (or {@link Expr}) to build * an expression that uses OR like Expression e = Expr.or(..., ...); *

*/ public static ExpressionFactory getExpressionFactory() { return serverMgr.getPrimaryServer().getExpressionFactory(); } /** * Register the server with this Ebean singleton. Specify if the registered * server is the primary/default server. */ protected static void register(EbeanServer server, boolean isPrimaryServer) { serverMgr.register(server, isPrimaryServer); } /** * Return the next identity value for a given bean type. *

* This will only work when a IdGenerator is on this bean type such as a DB * sequence or UUID. *

*

* For DB's supporting getGeneratedKeys and sequences such as Oracle10 you do * not need to use this method generally. It is made available for more * complex cases where it is useful to get an ID prior to some processing. *

*/ public static Object nextId(Class beanType) { return serverMgr.getPrimaryServer().nextId(beanType); } /** * Log a comment to the transaction log of the current transaction. *

* If there is no current transaction this comment does not go anywhere. *

*/ public static void logComment(String msg) { serverMgr.getPrimaryServer().logComment(msg); } /** * Start a new explicit transaction. *

* The transaction is stored in a ThreadLocal variable and typically you only * need to use the returned Transaction IF you wish to do things like * use batch mode, change the transaction isolation level, use savepoints or * log comments to the transaction log. *

*

* Example of using a transaction to span multiple calls to find(), save() * etc. *

* *
   * // start a transaction (stored in a ThreadLocal)
   * Ebean.beginTransaction(); 
   * try { 
   * 	Order order = Ebean.find(Order.class,10); ...
   * 
   * 	Ebean.save(order);
   * 
   * 	Ebean.commitTransaction();
   * 
   * } finally { 
   * 	// rollback if we didn't commit 
   * 	// i.e. an exception occurred before commitTransaction(). 
   * 	Ebean.endTransaction(); 
   * }
   * 
* *

* If you want to externalise the transaction management then you should be * able to do this via EbeanServer. Specifically with EbeanServer you can pass * the transaction to the various find() and save() execute() methods. This * gives you the ability to create the transactions yourself externally from * Ebean and pass those transactions through to the various methods available * on EbeanServer. *

*/ public static Transaction beginTransaction() { return serverMgr.getPrimaryServer().beginTransaction(); } /** * Start a transaction additionally specifying the isolation level. * * @param isolation * the Transaction isolation level * */ public static Transaction beginTransaction(TxIsolation isolation) { return serverMgr.getPrimaryServer().beginTransaction(isolation); } /** * Returns the current transaction or null if there is no current transaction * in scope. */ public static Transaction currentTransaction() { return serverMgr.getPrimaryServer().currentTransaction(); } /** * Commit the current transaction. */ public static void commitTransaction() { serverMgr.getPrimaryServer().commitTransaction(); } /** * Rollback the current transaction. */ public static void rollbackTransaction() { serverMgr.getPrimaryServer().rollbackTransaction(); } /** * If the current transaction has already been committed do nothing otherwise * rollback the transaction. *

* Useful to put in a finally block to ensure the transaction is ended, rather * than a rollbackTransaction() in each catch block. *

*

* Code example: *

* *
   * Ebean.beginTransaction();
   * try {
   *   // do some fetching and or persisting
   *   // commit at the end Ebean.commitTransaction();
   * 
   * } finally {
   *   // if commit didn't occur then rollback the transaction
   *   Ebean.endTransaction();
   * }
   * 
*/ public static void endTransaction() { serverMgr.getPrimaryServer().endTransaction(); } /** * Validate a bean. *

* This will validate all of the properties on the bean in a recursive * fashion. Typically if cascade save or delete is on then the validation will * cascade those same associations. *

*

* If no errors are detected then this returns null. Otherwise the returned * InvalidValue holds the errors from all the rules tested. Use * {@link InvalidValue#getErrors()} to get the list of errors that occurred. *

* * @return a InvalidValue holding the errors or null */ public static InvalidValue validate(Object bean) { return serverMgr.getPrimaryServer().validate(bean); } /** * Validate a bean property. *

* If value passed in is null, then the property value from the bean is used. *

*

* If no errors are detected an empty array is returned. *

* * @param bean * the bean used if value is null * @param propertyName * the property to validate * @param value * the value to validate. If this is null then the value from the * bean is used to validate. * @return a InvalidValue holding the errors for this property (returns an * empty array if there are no errors). */ public static InvalidValue[] validate(Object bean, String propertyName, Object value) { return serverMgr.getPrimaryServer().validate(bean, propertyName, value); } /** * Return a map of the differences between two objects of the same type. *

* When null is passed in for b, then the 'OldValues' of a is used for the * difference comparison. *

*/ public static Map diff(Object a, Object b) { return serverMgr.getPrimaryServer().diff(a, b); } /** * Either Insert or Update the bean depending on its state. *

* If there is no current transaction one will be created and committed for * you automatically. *

*

* Save can cascade along relationships. For this to happen you need to * specify a cascade of CascadeType.ALL or CascadeType.PERSIST on the * OneToMany, OneToOne or ManyToMany annotation. *

*

* In this example below the details property has a CascadeType.ALL set so * saving an order will also save all its details. *

* *
   * public class Order { ...
   * 	
   * 	@OneToMany(cascade=CascadeType.ALL, mappedBy="order")
   * 	@JoinColumn(name="order_id") 
   * 	List<OrderDetail> details; 
   * 	... 
   * }
   * 
* *

* When a save cascades via a OneToMany or ManyToMany Ebean will automatically * set the 'parent' object to the 'detail' object. In the example below in * saving the order and cascade saving the order details the 'parent' order * will be set against each order detail when it is saved. *

*/ public static void save(Object bean) throws OptimisticLockException { serverMgr.getPrimaryServer().save(bean); } /** * Force an update using the bean updating the non-null properties. *

* You can use this method to FORCE an update to occur (even on a bean that * has not been fetched but say built from JSON or XML). When * {@link Ebean#save(Object)} is used Ebean determines whether to use an * insert or an update based on the state of the bean. Using this method will * force an update to occur. *

*

* It is expected that this method is most useful in stateless REST services * or web applications where you have the values you wish to update but no * existing bean. *

*

* For updates against beans that have not been fetched (say built from JSON * or XML) this will treat deleteMissingChildren=true and will delete any * 'missing children'. Refer to * {@link EbeanServer#update(Object, Set, Transaction, boolean, boolean)}. *

* *
   * 
   * Customer c = new Customer();
   * c.setId(7);
   * c.setName("ModifiedNameNoOCC");
   * 
   * // generally you should set the version property
   * // so that Optimistic Concurrency Checking is used.
   * // If a version property is not set then no Optimistic
   * // Concurrency Checking occurs for the update
   * // c.setLastUpdate(lastUpdateTime);
   * 
   * // by default the Non-null properties
   * // are included in the update
   * Ebean.update(c);
   * 
   * 
*/ public static void update(Object bean) { serverMgr.getPrimaryServer().update(bean); } /** * Force an update using the bean explicitly stating the properties to update. *

* If you don't specify explicit properties to use in the update then the * non-null properties are included in the update. *

*

* For updates against beans that have not been fetched (say built from JSON * or XML) this will treat deleteMissingChildren=true and will delete any * 'missing children'. Refer to * {@link EbeanServer#update(Object, Set, Transaction, boolean, boolean)}. *

* * @param bean * The bean holding the values to be included in the update. * @param updateProps * the explicit set of properties to include in the update (can be * null). */ public static void update(Object bean, Set updateProps) { serverMgr.getPrimaryServer().update(bean, updateProps); } /** * Save all the beans from an Iterator. */ public static int save(Iterator iterator) throws OptimisticLockException { return serverMgr.getPrimaryServer().save(iterator); } /** * Save all the beans from a Collection. */ public static int save(Collection c) throws OptimisticLockException { return save(c.iterator()); } /** * Delete the associations (from the intersection table) of a ManyToMany given * the owner bean and the propertyName of the ManyToMany collection. *

* Typically these deletions occur automatically when persisting a ManyToMany * collection and this provides a way to invoke those deletions directly. *

* * @return the number of associations deleted (from the intersection table). */ public static int deleteManyToManyAssociations(Object ownerBean, String propertyName) { return serverMgr.getPrimaryServer().deleteManyToManyAssociations(ownerBean, propertyName); } /** * Save the associations of a ManyToMany given the owner bean and the * propertyName of the ManyToMany collection. *

* Typically the saving of these associations (inserting into the intersection * table) occurs automatically when persisting a ManyToMany. This provides a * way to invoke those insertions directly. *

*

* You can use this when the collection is new and in this case all the * entries in the collection are treated as additions are result in inserts * into the intersection table. *

*/ public static void saveManyToManyAssociations(Object ownerBean, String propertyName) { serverMgr.getPrimaryServer().saveManyToManyAssociations(ownerBean, propertyName); } /** * Save the associated collection or bean given the property name. *

* This is similar to performing a save cascade on a specific property * manually/programmatically. *

*

* Note that you can turn on/off cascading for a transaction via * {@link Transaction#setPersistCascade(boolean)} *

* * @param ownerBean * the bean instance holding the property we want to save * @param propertyName * the property we want to save */ public static void saveAssociation(Object ownerBean, String propertyName) { serverMgr.getPrimaryServer().saveAssociation(ownerBean, propertyName); } /** * Delete the bean. *

* If there is no current transaction one will be created and committed for * you automatically. *

*/ public static void delete(Object bean) throws OptimisticLockException { serverMgr.getPrimaryServer().delete(bean); } /** * Delete the bean given its type and id. */ public static int delete(Class beanType, Object id) { return serverMgr.getPrimaryServer().delete(beanType, id); } /** * Delete several beans given their type and id values. */ public static void delete(Class beanType, Collection ids) { serverMgr.getPrimaryServer().delete(beanType, ids); } /** * Delete all the beans from an Iterator. */ public static int delete(Iterator it) throws OptimisticLockException { return serverMgr.getPrimaryServer().delete(it); } /** * Delete all the beans from a Collection. */ public static int delete(Collection c) throws OptimisticLockException { return delete(c.iterator()); } /** * Refresh the values of a bean. *

* Note that this does not refresh any OneToMany or ManyToMany properties. *

*/ public static void refresh(Object bean) { serverMgr.getPrimaryServer().refresh(bean); } /** * Refresh a 'many' property of a bean. * *
   * Order order = ...;
   * ...
   * // refresh the order details...
   * Ebean.refreshMany(order, "details");
   * 
* * @param bean * the entity bean containing the List Set or Map to refresh. * @param manyPropertyName * the property name of the List Set or Map to refresh. */ public static void refreshMany(Object bean, String manyPropertyName) { serverMgr.getPrimaryServer().refreshMany(bean, manyPropertyName); } /** * Get a reference object. *

* This is sometimes described as a proxy (with lazy loading). *

* *
   * Product product = Ebean.getReference(Product.class, 1);
   * 
   * // You can get the id without causing a fetch/lazy load
   * Integer productId = product.getId();
   * 
   * // If you try to get any other property a fetch/lazy loading will occur
   * // This will cause a query to execute...
   * String name = product.getName();
   * 
* * @param beanType * the type of entity bean * @param id * the id value */ public static T getReference(Class beanType, Object id) { return serverMgr.getPrimaryServer().getReference(beanType, id); } /** * Sort the list using the sortByClause which can contain a comma delimited * list of property names and keywords asc, desc, nullsHigh and nullsLow. *
    *
  • asc - ascending order (which is the default)
  • *
  • desc - Descending order
  • *
  • nullsHigh - Treat null values as high/large values (which is the * default)
  • *
  • nullsLow- Treat null values as low/very small values
  • *
*

* If you leave off any keywords the defaults are ascending order and treating * nulls as high values. *

*

* Note that the sorting uses a Comparator and Collections.sort(); and does * not invoke a DB query. *

* *
   * 
   * // find orders and their customers
   * List<Order> list = Ebean.find(Order.class)
   *     .fetch("customer")
   *     .orderBy("id")
   *     .findList();
   * 
   * // sort by customer name ascending, then by order shipDate
   * // ... then by the order status descending
   * Ebean.sort(list, "customer.name, shipDate, status desc");
   * 
   * // sort by customer name descending (with nulls low)
   * // ... then by the order id
   * Ebean.sort(list, "customer.name desc nullsLow, id");
   * 
   * 
* * @param list * the list of entity beans * @param sortByClause * the properties to sort the list by */ public static void sort(List list, String sortByClause) { serverMgr.getPrimaryServer().sort(list, sortByClause); } /** * Find a bean using its unique id. This will not use caching. * *
   * // Fetch order 1
   * Order order = Ebean.find(Order.class, 1);
   * 
* *

* If you want more control over the query then you can use createQuery() and * Query.findUnique(); *

* *
   * // ... additionally fetching customer, customer shipping address,
   * // order details, and the product associated with each order detail.
   * // note: only product id and name is fetch (its a "partial object").
   * // note: all other objects use "*" and have all their properties fetched.
   * 
   * Query<Order> query = Ebean.createQuery(Order.class);
   * query.setId(1);
   * query.fetch("customer");
   * query.fetch("customer.shippingAddress");
   * query.fetch("details");
   * 
   * // fetch associated products but only fetch their product id and name
   * query.fetch("details.product", "name");
   * 
   * // traverse the object graph...
   * 
   * Order order = query.findUnique();
   * Customer customer = order.getCustomer();
   * Address shippingAddress = customer.getShippingAddress();
   * List<OrderDetail> details = order.getDetails();
   * OrderDetail detail0 = details.get(0);
   * Product product = detail0.getProduct();
   * String productName = product.getName();
   * 
* * @param beanType * the type of entity bean to fetch * @param id * the id value */ public static T find(Class beanType, Object id) { return serverMgr.getPrimaryServer().find(beanType, id); } /** * Create a SqlQuery for executing native sql * query statements. *

* Note that you can use raw SQL with entity beans, refer to the SqlSelect * annotation for examples. *

*/ public static SqlQuery createSqlQuery(String sql) { return serverMgr.getPrimaryServer().createSqlQuery(sql); } /** * Create a named sql query. *

* The query statement will be defined in a deployment orm xml file. *

* * @param namedQuery * the name of the query */ public static SqlQuery createNamedSqlQuery(String namedQuery) { return serverMgr.getPrimaryServer().createNamedSqlQuery(namedQuery); } /** * Create a sql update for executing native dml statements. *

* Use this to execute a Insert Update or Delete statement. The statement will * be native to the database and contain database table and column names. *

*

* See {@link SqlUpdate} for example usage. *

*

* Where possible it would be expected practice to put the statement in a orm * xml file (named update) and use {@link #createNamedSqlUpdate(String)} . *

*/ public static SqlUpdate createSqlUpdate(String sql) { return serverMgr.getPrimaryServer().createSqlUpdate(sql); } /** * Create a CallableSql to execute a given stored procedure. * * @see CallableSql */ public static CallableSql createCallableSql(String sql) { return serverMgr.getPrimaryServer().createCallableSql(sql); } /** * Create a named sql update. *

* The statement (an Insert Update or Delete statement) will be defined in a * deployment orm xml file. *

* *
   * // Use a namedQuery
   * UpdateSql update = Ebean.createNamedSqlUpdate("update.topic.count");
   * 
   * update.setParameter("count", 1);
   * update.setParameter("topicId", 50);
   * 
   * int modifiedCount = update.execute();
   * 
*/ public static SqlUpdate createNamedSqlUpdate(String namedQuery) { return serverMgr.getPrimaryServer().createNamedSqlUpdate(namedQuery); } /** * Return a named Query that will have defined fetch paths, predicates etc. *

* The query is created from a statement that will be defined in a deployment * orm xml file or NamedQuery annotations. The query will typically already * define fetch paths, predicates, order by clauses etc so often you will just * need to bind required parameters and then execute the query. *

* *
   * // example
   * Query<Order> query = Ebean.createNamedQuery(Order.class, "new.for.customer");
   * query.setParameter("customerId", 23);
   * List<Order> newOrders = query.findList();
   * 
* * @param beanType * the class of entity to be fetched * @param namedQuery * the name of the query */ public static Query createNamedQuery(Class beanType, String namedQuery) { return serverMgr.getPrimaryServer().createNamedQuery(beanType, namedQuery); } /** * Create a query using the query language. *

* Note that you are allowed to add additional clauses using where() as well * as use fetch() and setOrderBy() after the query has been created. *

*

* Note that this method signature used to map to named queries and that has * moved to {@link #createNamedQuery(Class, String)}. *

* *
   * 
   * String q = "find order fetch details where status = :st";
   * 
   * List<Order> newOrders = Ebean.createQuery(Order.class, q)
   *     .setParameter("st", Order.Status.NEW)
   *     .findList();
   * 
* * @param query * the object query */ public static Query createQuery(Class beanType, String query) { return serverMgr.getPrimaryServer().createQuery(beanType, query); } /** * Create a named orm update. The update statement is specified via the * NamedUpdate annotation. *

* The orm update differs from the SqlUpdate in that it uses the bean name and * bean property names rather than table and column names. *

*

* Note that named update statements can be specified in raw sql (with column * and table names) or using bean name and bean property names. This can be * specified with the isSql flag. *

*

* Example named updates: *

* *
   * package app.data;
   * 
   * import ...
   * 
   * @NamedUpdates(value = { 
   * 	@NamedUpdate( name = "setTitle", 
   * 		isSql = false, 
   * 		notifyCache = false, 
   * 		update = "update topic set title = :title, postCount = :postCount where id = :id"), 
   * 	@NamedUpdate( name = "setPostCount",
   * 		notifyCache = false,
   * 		update = "update f_topic set post_count = :postCount where id = :id"), 
   * 	@NamedUpdate( name = "incrementPostCount", 
   * 		notifyCache = false, 
   * 		isSql = false,
   * 		update = "update Topic set postCount = postCount + 1 where id = :id") }) 
   * @Entity 
   * @Table(name = "f_topic") 
   * public class Topic { ...
   * 
* *

* Example using a named update: *

* *
   * Update<Topic> update = Ebean.createNamedUpdate(Topic.class, "setPostCount");
   * update.setParameter("postCount", 10);
   * update.setParameter("id", 3);
   * 
   * int rows = update.execute();
   * System.out.println("rows updated: " + rows);
   * 
*/ public static Update createNamedUpdate(Class beanType, String namedUpdate) { return serverMgr.getPrimaryServer().createNamedUpdate(beanType, namedUpdate); } /** * Create a orm update where you will supply the insert/update or delete * statement (rather than using a named one that is already defined using the * @NamedUpdates annotation). *

* The orm update differs from the sql update in that it you can use the bean * name and bean property names rather than table and column names. *

*

* An example: *

* *
   * 
   * // The bean name and properties - "topic","postCount" and "id"
   * 
   * // will be converted into their associated table and column names
   * String updStatement = "update topic set postCount = :pc where id = :id";
   * 
   * Update<Topic> update = Ebean.createUpdate(Topic.class, updStatement);
   * 
   * update.set("pc", 9);
   * update.set("id", 3);
   * 
   * int rows = update.execute();
   * System.out.println("rows updated:" + rows);
   * 
*/ public static Update createUpdate(Class beanType, String ormUpdate) { return serverMgr.getPrimaryServer().createUpdate(beanType, ormUpdate); } /** * Create a CsvReader for a given beanType. */ public static CsvReader createCsvReader(Class beanType) { return serverMgr.getPrimaryServer().createCsvReader(beanType); } /** * Create a query for a type of entity bean. *

* You can use the methods on the Query object to specify fetch paths, * predicates, order by, limits etc. *

*

* You then use findList(), findSet(), findMap() and findUnique() to execute * the query and return the collection or bean. *

*

* Note that a query executed by {@link Query#findList()} * {@link Query#findSet()} etc will execute against the same EbeanServer from * which is was created. *

* *
   * // Find order 2 additionally fetching the customer, details and details.product
   * // name.
   * 
   * Query<Order> query = Ebean.createQuery(Order.class);
   * query.fetch("customer");
   * query.fetch("details");
   * query.fetch("detail.product", "name");
   * query.setId(2);
   * 
   * Order order = query.findUnique();
   * 
   * // Find order 2 additionally fetching the customer, details and details.product
   * // name.
   * // Note: same query as above but using the query language
   * // Note: using a named query would be preferred practice
   * 
   * String oql = "find order fetch customer fetch details fetch details.product (name) where id = :orderId ";
   * 
   * Query<Order> query = Ebean.createQuery(Order.class);
   * query.setQuery(oql);
   * query.setParameter("orderId", 2);
   * 
   * Order order = query.findUnique();
   * 
   * // Using a named query
   * Query<Order> query = Ebean.createQuery(Order.class, "with.details");
   * query.setParameter("orderId", 2);
   * 
   * Order order = query.findUnique();
   * 
   * 
* * @param beanType * the class of entity to be fetched * @return A ORM Query object for this beanType */ public static Query createQuery(Class beanType) { return serverMgr.getPrimaryServer().createQuery(beanType); } /** * Create a query for a type of entity bean. *

* This is actually the same as {@link #createQuery(Class)}. The reason it * exists is that people used to JPA will probably be looking for a * createQuery method (the same as entityManager). *

* * @param beanType * the type of entity bean to find * @return A ORM Query object for this beanType */ public static Query find(Class beanType) { return serverMgr.getPrimaryServer().find(beanType); } /** * Create a filter for sorting and filtering lists of entities locally without * going back to the database. *

* This produces and returns a new list with the sort and filters applied. *

*

* Refer to {@link Filter} for an example of its use. *

*/ public static Filter filter(Class beanType) { return serverMgr.getPrimaryServer().filter(beanType); } /** * Execute a Sql Update Delete or Insert statement. This returns the number of * rows that where updated, deleted or inserted. If is executed in batch then * this returns -1. You can get the actual rowCount after commit() from * updateSql.getRowCount(). *

* If you wish to execute a Sql Select natively then you should use the * FindByNativeSql object. *

*

* Note that the table modification information is automatically deduced and * you do not need to call the Ebean.externalModification() method when you * use this method. *

*

* Example: *

* *
   * // example that uses 'named' parameters 
   * String s = "UPDATE f_topic set post_count = :count where id = :id"
   * 
   * SqlUpdate update = Ebean.createSqlUpdate(s);
   * 
   * update.setParameter("id", 1);
   * update.setParameter("count", 50);
   * 
   * int modifiedCount = Ebean.execute(update);
   * 
   * String msg = "There where " + modifiedCount + "rows updated";
   * 
* * @param sqlUpdate * the update sql potentially with bind values * * @return the number of rows updated or deleted. -1 if executed in batch. * * @see SqlUpdate * @see CallableSql * @see Ebean#execute(CallableSql) */ public static int execute(SqlUpdate sqlUpdate) { return serverMgr.getPrimaryServer().execute(sqlUpdate); } /** * For making calls to stored procedures. *

* Example: *

* *
   * String sql = "{call sp_order_modify(?,?,?)}";
   * 
   * CallableSql cs = Ebean.createCallableSql(sql);
   * cs.setParameter(1, 27);
   * cs.setParameter(2, "SHIPPED");
   * cs.registerOut(3, Types.INTEGER);
   * 
   * Ebean.execute(cs);
   * 
   * // read the out parameter
   * Integer returnValue = (Integer) cs.getObject(3);
   * 
* * @see CallableSql * @see Ebean#execute(SqlUpdate) */ public static int execute(CallableSql callableSql) { return serverMgr.getPrimaryServer().execute(callableSql); } /** * Execute a TxRunnable in a Transaction with an explicit scope. *

* The scope can control the transaction type, isolation and rollback * semantics. *

* *
   * // set specific transactional scope settings 
   * TxScope scope = TxScope.requiresNew().setIsolation(TxIsolation.SERIALIZABLE);
   * 
   * Ebean.execute(scope, new TxRunnable() { 
   * 	public void run() { 
   * 		User u1 = Ebean.find(User.class, 1); 
   * 		...
   * 
   * 	} 
   * });
   * 
*/ public static void execute(TxScope scope, TxRunnable r) { serverMgr.getPrimaryServer().execute(scope, r); } /** * Execute a TxRunnable in a Transaction with the default scope. *

* The default scope runs with REQUIRED and by default will rollback on any * exception (checked or runtime). *

* *
   * Ebean.execute(new TxRunnable() {
   *   public void run() {
   *     User u1 = Ebean.find(User.class, 1);
   *     User u2 = Ebean.find(User.class, 2);
   * 
   *     u1.setName("u1 mod");
   *     u2.setName("u2 mod");
   * 
   *     Ebean.save(u1);
   *     Ebean.save(u2);
   *   }
   * });
   * 
*/ public static void execute(TxRunnable r) { serverMgr.getPrimaryServer().execute(r); } /** * Execute a TxCallable in a Transaction with an explicit scope. *

* The scope can control the transaction type, isolation and rollback * semantics. *

* *
   * // set specific transactional scope settings 
   * TxScope scope = TxScope.requiresNew().setIsolation(TxIsolation.SERIALIZABLE);
   * 
   * Ebean.execute(scope, new TxCallable<String>() {
   * 	public String call() { 
   * 		User u1 = Ebean.find(User.class, 1); 
   * 		...
   * 		return u1.getEmail(); 
   * 	} 
   * });
   * 
* */ public static T execute(TxScope scope, TxCallable c) { return serverMgr.getPrimaryServer().execute(scope, c); } /** * Execute a TxCallable in a Transaction with the default scope. *

* The default scope runs with REQUIRED and by default will rollback on any * exception (checked or runtime). *

*

* This is basically the same as TxRunnable except that it returns an Object * (and you specify the return type via generics). *

* *
   * Ebean.execute(new TxCallable<String>() {
   *   public String call() {
   *     User u1 = Ebean.find(User.class, 1);
   *     User u2 = Ebean.find(User.class, 2);
   * 
   *     u1.setName("u1 mod");
   *     u2.setName("u2 mod");
   * 
   *     Ebean.save(u1);
   *     Ebean.save(u2);
   * 
   *     return u1.getEmail();
   *   }
   * });
   * 
*/ public static T execute(TxCallable c) { return serverMgr.getPrimaryServer().execute(c); } /** * Inform Ebean that tables have been modified externally. These could be the * result of from calling a stored procedure, other JDBC calls or external * programs including other frameworks. *

* If you use Ebean.execute(UpdateSql) then the table modification information * is automatically deduced and you do not need to call this method yourself. *

*

* This information is used to invalidate objects out of the cache and * potentially text indexes. This information is also automatically broadcast * across the cluster. *

*

* If there is a transaction then this information is placed into the current * transactions event information. When the transaction is commited this * information is registered (with the transaction manager). If this * transaction is rolled back then none of the transaction event information * registers including the information you put in via this method. *

*

* If there is NO current transaction when you call this method then this * information is registered immediately (with the transaction manager). *

* * @param tableName * the name of the table that was modified * @param inserts * true if rows where inserted into the table * @param updates * true if rows on the table where updated * @param deletes * true if rows on the table where deleted */ public static void externalModification(String tableName, boolean inserts, boolean updates, boolean deletes) { serverMgr.getPrimaryServer().externalModification(tableName, inserts, updates, deletes); } /** * Return the BeanState for a given entity bean. *

* This will return null if the bean is not an enhanced (or subclassed) entity * bean. *

*/ public static BeanState getBeanState(Object bean) { return serverMgr.getPrimaryServer().getBeanState(bean); } /** * Return the manager of the server cache ("L2" cache). * */ public static ServerCacheManager getServerCacheManager() { return serverMgr.getPrimaryServer().getServerCacheManager(); } /** * Return the BackgroundExecutor service for asynchronous processing of * queries. */ public static BackgroundExecutor getBackgroundExecutor() { return serverMgr.getPrimaryServer().getBackgroundExecutor(); } /** * Run the cache warming queries on all bean types that have one defined for * the default/primary EbeanServer. *

* A cache warming query can be defined via {@link CacheStrategy}. *

*/ public static void runCacheWarming() { serverMgr.getPrimaryServer().runCacheWarming(); } /** * Run the cache warming query for a specific bean type for the * default/primary EbeanServer. *

* A cache warming query can be defined via {@link CacheStrategy}. *

*/ public static void runCacheWarming(Class beanType) { serverMgr.getPrimaryServer().runCacheWarming(beanType); } /** * Create a JsonContext that will use the default configuration options. */ public static JsonContext createJsonContext() { return serverMgr.getPrimaryServer().createJsonContext(); } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy