/** * Redistribution and use of this software and associated documentation * ("Software"), with or without modification, are permitted provided * that the following conditions are met: * * 1. Redistributions of source code must retain copyright * statements and notices. Redistributions must also contain a * copy of this document. * * 2. Redistributions in binary form must reproduce the * above copyright notice, this list of conditions and the * following disclaimer in the documentation and/or other * materials provided with the distribution. * * 3. The name "Exolab" must not be used to endorse or promote * products derived from this Software without prior written * permission of Intalio, Inc. For written permission, * please contact info@exolab.org. * * 4. Products derived from this Software may not be called "Exolab" * nor may "Exolab" appear in their names without prior written * permission of Intalio, Inc. Exolab is a registered * trademark of Intalio, Inc. * * 5. Due credit should be given to the Exolab Project * (http://www.exolab.org/). * * THIS SOFTWARE IS PROVIDED BY INTALIO, INC. AND CONTRIBUTORS * ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL * INTALIO, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. * * Copyright 1999 (C) Intalio, Inc. All Rights Reserved. * * $Id$ */ package org.exolab.castor.jdo; import org.exolab.castor.mapping.AccessMode; import org.exolab.castor.persist.PersistenceInfoGroup; import org.exolab.castor.persist.spi.Identity; /** * An open connection to the database. This object represents an open * connection to the database that can be used to perform transactional * operations on the database. * <p> * Database operations can only be performed in the context of a * transaction. Client applications should begin and commit a transaction * using the {@link #begin} and {@link #commit} methods. Server * applications should use implicit transaction demaraction by the * container or explicit transaction demarcation using <tt>javax.transaction.UserTransaction</tt>. * <p> * All objects queried and created during a transaction are persistent. * Changes to persistent objects will be stored in the database when * the transaction commits. Changes will not be stored if the transaction * is rolled back or fails to commit. * <p> * Once the transaction has committed or rolled back, all persistent * objects become transient. Opening a new transaction does not make * these objects persistent. * <p> * For example: * <pre> * Database db; * Query oql; * QueryResults results; * Product prod; * * <font color="red">// Open a database and start a transaction</font> * db = jdo.getDatabase(); * db.begin(); * <font color="red">// Select all the products in a given group</font> * oql = db.getOQLQuery( "SELECT p FROM Product p WHERE group=$"); * oql.bind( groupId ); * results = oql.execute(); * while ( results.hasMore() ) { * <font color="red">// A 25% mark down for each product and mark as sale</font> * prod = (Product) results.next(); * prod.markDown( 0.25 ); * prod.setOnSale( true ); * } * <font color="red">// Commit all changes, close the database</font> * db.commit(); * db.close(); * </pre> * * @author <a href="arkin@intalio.com">Assaf Arkin</a> * @version $Revision$ $Date: 2006-03-16 16:04:24 -0700 (Thu, 16 Mar 2006) $ * @see JDOManager#getDatabase() * @see Query */ public interface Database { /** Read only access. Used with queries and the {@link #load(Class,Object)} method to load * objects as read-only. * <br/> * Read-only objects are not persistent and changes to these objects are not reflected in * the database when the transaction commits. */ AccessMode READONLY = AccessMode.ReadOnly; /** Shared access. Used with queries and the {@link #load(Class,Object)} method to load * objects with shared access. * <br/> * Shared access allows the same record to be accessed by two concurrent transactions, each * with it's own view (object). * <br/> * These objects acquire a read lock which escalated to a write lock when the transaction * commits if the object has been modified. Dirty checking is enabled for all fields marked * as such, and a cached copy is used to populate the object. */ AccessMode SHARED = AccessMode.Shared; /** Exclusive access. Used with queries and the {@link #load(Class,Object)} method to load * objects with exclusive access. * <br/> * Exclusive access prevents two concurrent transactions from accessing the same record. In * exclusive mode objects acquire a write lock, and concurrent transactions will block until * the lock is released at commit time. * <br/> * Dirty checking is enabled for all fields marked as such. When an object is first loaded * in the transaction, it will be synchronized with the database and not populated from the * cache. */ AccessMode EXCLUSIVE = AccessMode.Exclusive; /** Database lock access. Used with queries and the {@link #load(Class,Object)} method to * load objects with a database lock. * <br/> * Database lock prevents two concurrent transactions from accessing the same record either * through Castor or direct database access by acquiring a write lock in the select statement. * Concurrent transactions will block until the lock is released at commit time. * <br/> * When an object is first loaded in the transaction, it will be synchronized with the * database and not populated from the cache. Dirty checking is not required. */ AccessMode DBLOCKED = AccessMode.DbLocked; /** * Creates an OQL query with no statement. {@link OQLQuery#create} * must be called before the query can be executed. * * @return An OQL query */ OQLQuery getOQLQuery(); /** * Creates an OQL query from the supplied statement. * @param oql An OQL query statement * @return An OQL query * @throws PersistenceException */ OQLQuery getOQLQuery(String oql) throws PersistenceException; /** * Creates an empty query. The query must be created before * it can be executed. * * @return A query */ Query getQuery(); /** * Creates an OQL query based upon a named query as defined in the * mapping file. {@link OQLQuery#create} * * @param name Name of the (named) query to create. * @return An OQL query * @throws PersistenceException */ OQLQuery getNamedQuery(String name) throws PersistenceException; /** * Creates an OQL query instance based upon a native SQL query and a returning * (resulting) class. * * @param sql Native SQL query to be used. * @param result Class that is result of the query. * @return An OQL query * @throws PersistenceException */ OQLQuery getNativeQuery(String sql, Class<?> result) throws PersistenceException; PersistenceInfoGroup getScope(); /** * Return the name of the database. * * @return The database name. */ String getDatabaseName(); /** * Load an object of the specified type and given identity. * Once loaded the object is persistent. Calling this method with * the same identity in the same transaction will return the same * object. This method is equivalent to a query that returns a * single object. If the identity spans on more than one field, all * of the identity fields can be wrapped in a Complex object. * * @param type The object's type * @param identity The object's identity * @return The object instance. * @throws ObjectNotFoundException No object of the given type and * identity was found in persistent storage * @throws LockNotGrantedException Timeout or deadlock occured * attempting to acquire a lock on the object * @throws TransactionNotInProgressException Method called while * transaction is not in progress * @throws PersistenceException An error reported by the * persistence engine */ <T> T load(final Class<T> type, final Object identity) throws PersistenceException; /** * <p> * Load an object of the specified type and given identity. * Once loaded the object is persistent. Calling this method with * the same identity in the same transaction will return the same * object. This method is equivalent to a query that returns a * single object. * * @param type The object's type * @param identity The object's identity * @param mode The access mode * @return The object instance. * @throws ObjectNotFoundException No object of the given type and * identity was found in persistent storage * @throws LockNotGrantedException Timeout or deadlock occured * attempting to acquire a lock on the object * @throws TransactionNotInProgressException Method called while * transaction is not in progress * @throws PersistenceException An error reported by the * persistence engine */ <T> T load(final Class<T> type, final Object identity, final AccessMode mode) throws PersistenceException; /** * <p> * Load an object of the specified type and given identity into * a given instance of object. * * Once loaded the object is persistent. Calling this method with * the same identity in the same transaction will return the same * object. This method is equivalent to a query that returns a * single object. If the identity spans on more than one field, all * of the identity fields can be wrapped in a Complex object. * * @param type The object's type * @param identity The object's identity * @param object The object instance to be loaded into * @return The object instance. * @throws ObjectNotFoundException No object of the given type and * identity was found in persistent storage * @throws LockNotGrantedException Timeout or deadlock occured * attempting to acquire a lock on the object * @throws TransactionNotInProgressException Method called while * transaction is not in progress * @throws PersistenceException An error reported by the * persistence engine */ <T> T load(final Class<T> type, final Object identity, final Object object) throws PersistenceException; /** * Creates a new object in persistent storage. The object will be * persisted only if the transaction commits. * <p> * If the object has an identity then duplicate identity check happens * in this method, and the object is visible to queries in this * transaction. If the identity is null, duplicate identity check * occurs when the transaction completes and the object is not * visible to queries until the transaction commits. * * @param object The object to create * @throws TransactionNotInProgressException Method called while * transaction is not in progress * @throws DuplicateIdentityException An object with this identity * already exists in persistent storage * @throws ClassNotPersistenceCapableException The class is not * persistent capable * @throws PersistenceException An error reported by the * persistence engine */ void create(Object object) throws PersistenceException; /** * Removes the object from persistent storage. The deletion will * take effect only if the transaction is committed, but the * object is no longer visible to queries in the current transaction * and locks for access from other transactions will block until * this transaction completes. * * @param object The object to remove * @throws TransactionNotInProgressException Method called while * transaction is not in progress * @throws ObjectNotPersistentException The object has not been * queried or created in this transaction * @throws LockNotGrantedException Timeout or deadlock occured * attempting to acquire a lock on the object * @throws PersistenceException An error reported by the * persistence engine */ void remove(Object object) throws PersistenceException; /** * Update a data object which is queried/loaded/created in <b>another * transaction</b>. This method is used only for long transaction * support. Calling this method for data object queried/loaded/created * in the same transaction results in Exception. * <p> * For example, the data object may be sent to a client application and * dispayed to a user. After that the objects is being modified in the * client application, the object returns back and is update to the * database in the second transaction. * <p> * See <a href="http://castor.exolab.org/long-transact.html">Long * Transaction</a> on Castor website. * * @param object The object to create * @throws TransactionNotInProgressException Method called while * transaction is not in progress * @throws ClassNotPersistenceCapableException The class is not * persistent capable * @throws PersistenceException An error reported by the * persistence engine */ void update(Object object) throws PersistenceException; /** * Acquire a soft write lock on the object. Read locks are implicitly * available when the object is queried. A write lock is only * granted for objects that are created or deleted or for objects * loaded in <tt>exclusive</tt> mode - this method can obtain such a * lock explicitly. * <p> * A soft lock is acquired in memory, not in the database. To acquire * a lock in the database, use the <tt>locked</tt> access mode. * <p> * If the object already has a write lock in this * transaction or a read lock in this transaction but no read lock * in any other transaction, a write lock is obtained. If this * object has a read lock in any other transaction this method * will block until the other transaction will release its lock. * If the timeout has elapsed or a deadlock has been detected, * an exception will be thrown but the current lock will be retained. * * @param object The object to lock * @throws TransactionNotInProgressException Method called while * transaction is not in progress * @throws ObjectNotPersistentException The object has not been * queried or created in this transaction * @throws LockNotGrantedException Timeout or deadlock occured * attempting to acquire a lock on the object * @throws PersistenceException An error reported by the * persistence engine */ void lock(Object object) throws PersistenceException; /** * Begin a new transaction. A transaction must be open in order * to query and persist objects. * * @throws PersistenceException A transaction is already open on * this database, or an error reported by the persistence engine */ void begin() throws PersistenceException; /** * Return if the current transaction is set to autoStore, it there is * transaction active. If there is no active transaction, return if * the next transaction will be set to autoStore. * <p> * If autoStore is set on. AutoStore will create * all reachable object if the object is not loaded from the * transaction. If it is turn off, only dependent object will * be created automatically. * @return True if the current transaction is set to 'autoStore'. * * @deprecated As of Castor 1.3.2, please use the 'cascading' attribute * of the field mapping instead. */ boolean isAutoStore(); /** * True if autoStore is set on. * <p> * This method should be called before begin(). * <p> * If autoStore is set, and db.create( theDataObject ) is called, * Castor will create theDataObject, and create each object * that does not exist in the transaction and reachable from * theDataObject. * <p> * If db.update( theDataObject ), and theDataObject is * loaded/queried/created in a previous transaction, Castor * will let theDataObject, and all reachable object from * theDataObject, participate in the current transaction. * <p> * If autoStore is not set, Castor will only create/update/store * dependent object, and related objects must be created/update * explicitly. * @param autoStore True if this feature should be enabled. * * @deprecated As of Castor 1.3.2, please use the 'cascading' attribute * of the field mapping instead. */ void setAutoStore(boolean autoStore); /** * Commits and closes the transaction. All changes made to persistent * objects during the transaction are made persistent; objects created * during the transaction are made durable; and, objects removed during * the transaction are removed from the database. * <p> * In other words, any modifications to any data objects which are * queried/loaded/created/update to this database is automatically * stored to the database and visible to subsequence transactions. * (ie. update is solely used for long transaction support and should * not be called for any data object queried/loaded/created in the * this transaction.) * <p> * If the transaction cannot commit, the entire transaction rolls * back and a {@link TransactionAbortedException} exception is * thrown. * <p> * After this method returns, the transaction is closed and all * persistent objects are transient. Using {@link #begin} to open a * new transaction will not restore objects to their persistent * stage. * * @throws TransactionNotInProgressException Method called while * transaction is not in progress * @throws TransactionAbortedException The transaction cannot * commit and has been rolled back */ void commit() throws TransactionNotInProgressException, TransactionAbortedException; /** * Rolls back and closes the transaction. All changes made to * persistent objects during the transaction are lost, objects * created during the transaction are not made durable and objects * removed during the transaction continue to exist. * * @throws TransactionNotInProgressException Method called while * transaction is not in progress */ void rollback() throws TransactionNotInProgressException; /** * Returns true if a transaction is currently active. * * @return True if a transaction is active */ boolean isActive(); /** * Returns true if the database is closed. * * @return True if the database is closed */ boolean isClosed(); /** * Returns true if the specified object is currently locked. * * @param cls Class instance. * @param identity Object identity. * @return True if the object specified is locked; false otherwise. */ boolean isLocked (Class cls, Object identity) throws PersistenceException; /** * Closes the database. If a client transaction is in progress the * transaction will be rolled back and an exception thrown. * If an app-server transaction is in progress, the transaction * will commit/rollback when triggered by the application server. * * @throws PersistenceException An error occured while * attempting to close the database */ void close() throws PersistenceException; /** * Returns true if the entity is persistent. An entity is persistent * if it was created or loaded but not removed in this transaction. If * the entity was created or loaded in another transaction, or there is * no open transaction, this method returns false. * * @param entity The entity. * @return True if entity is persistent in this transaction. */ boolean isPersistent(Object entity); /** * Returns the object's identity. The identity will be determined by calling the * getters of the fields defined as identities in the mapping. If a mapping for * the objects class could not be found a ClassNotPersistenceCapableException * will be thrown. Null is only returned if the objects identity is null. It is * not required to have an active transaction when using this method. * <p> * <b>Note:</b> Prior to 0.9.9.1 release of castor the identity could only be * determined if the object took part in the transaction. If this was not the case, * the previous implementation also returned null. * * @param object The object. * @return The object's identity, or null. * @throws PersistenceException The class is not persistent capable. */ Identity getIdentity(Object object) throws PersistenceException; /** * Returns the current ClassLoader if one has been set for this Database instance. * * @return ClassLoader the current ClassLoader instance, <code>null</code> if no * ClassLoader's instance has been explicitely set. */ ClassLoader getClassLoader (); /** * Get's the CacheManager instance. * Call getCacheManager for every Database-instances. * * @return the CacheManager-instance. */ CacheManager getCacheManager(); /** * Gets the underlying JDBC connection. * * This is for <b>advanced</b> use only. Please make sure that you <b>never</b> * close this Connection instance, as it will be closed by Castor. * * @return the underlying JDBC connection, if present; otherwise null * @throws PersistenceException If the underlying JDBC connection cannot be obtained. */ java.sql.Connection getJdbcConnection() throws PersistenceException; }