FileDocCategorySizeDatePackage
QueryBasedValueHolder.javaAPI DocGlassfish v2 API7433Tue May 22 16:54:36 BST 2007oracle.toplink.essentials.internal.indirection

QueryBasedValueHolder

public class QueryBasedValueHolder extends DatabaseValueHolder
QueryBasedValueHolder wraps a database-stored object and implements behavior to access it. The object is read from the database by invoking a user-specified query.
see
ObjectLevelReadQuery
author
Dorin Sandu

Fields Summary
protected transient ReadQuery
query
Stores the query to be executed.
Constructors Summary
public QueryBasedValueHolder(ReadQuery query, AbstractRecord row, AbstractSession session)
Initialize the query-based value holder.

        this.row = row;
        this.session = session;

        // Make sure not to put a ClientSession or IsolatedClientSession in
        // the shared cache (indirectly).
        // Skip this if unitOfWork, for we use session.isUnitOfWork() to implement
        // isTransactionalValueholder(), saving us from needing a boolean instance variable.
        // If unitOfWork this safety measure is deferred until merge time with
        // releaseWrappedValuehHolder.
        // Note that if isolated session & query will return itself, which is safe
        // for if isolated it will not go in the shared cache.
        if (!session.isUnitOfWork()) {
            this.session = session.getRootSession(query);
        }
        this.query = query;
    
Methods Summary
protected oracle.toplink.essentials.queryframework.ReadQuerygetQuery()
Return the query.

        return query;
    
protected java.lang.Objectinstantiate()

        return instantiate(getSession());
    
protected java.lang.Objectinstantiate(oracle.toplink.essentials.internal.sessions.AbstractSession session)
Instantiate the object by executing the query on the session.

        if (session == null){
            throw ValidationException.instantiatingValueholderWithNullSession();
        }
        return session.executeQuery(getQuery(), getRow());
    
public java.lang.ObjectinstantiateForUnitOfWorkValueHolder(oracle.toplink.essentials.internal.indirection.UnitOfWorkValueHolder unitOfWorkValueHolder)
Triggers UnitOfWork valueholders directly without triggering the wrapped valueholder (this).

When in transaction and/or for pessimistic locking the UnitOfWorkValueHolder needs to be triggered directly without triggering the wrapped valueholder. However only the wrapped valueholder knows how to trigger the indirection, i.e. it may be a batchValueHolder, and it stores all the info like the row and the query. Note: This method is not thread-safe. It must be used in a synchronizaed manner

        return instantiate(unitOfWorkValueHolder.getUnitOfWork());
    
public booleanisPessimisticLockingValueHolder()
INTERNAL: Answers if this valueholder is a pessimistic locking one. Such valueholders are special in that they can be triggered multiple times by different UnitsOfWork. Each time a lock query will be issued. Hence even if instantiated it may have to be instantiated again, and once instantatiated all fields can not be reset.

Since locks will be issued each time this valueholder is triggered, triggering this directly on the session in auto commit mode will generate an exception. This only UnitOfWorkValueHolder's wrapping this can trigger it. Note: This method is not thread-safe. It must be used in a synchronizaed manner

        // Get the easy checks out of the way first.
        if ((getQuery() == null) || !getQuery().isObjectLevelReadQuery()) {
            return false;
        }
        ObjectLevelReadQuery query = (ObjectLevelReadQuery)getQuery();

        // Note even if the reference class is not locked, but the valueholder query
        // has joined attributes, then this may count as a lock query.
        // This means it is possible to trigger a valueholder to get an object which
        // is not to be pess. locked and get an exception for triggering it on the
        // session outside a transaction.
        return query.isLockQuery(getSession());
    
public voidreleaseWrappedValueHolder()
Releases a wrapped valueholder privately owned by a particular unit of work.

When unit of work clones are built directly from rows no object in the shared cache points to this valueholder, so it can store the unit of work as its session. However once that UnitOfWork commits and the valueholder is merged into the shared cache, the session needs to be reset to the root session, ie. the server session.

        AbstractSession session = getSession();
        if ((session != null) && session.isUnitOfWork()) {
            setSession(session.getRootSession(query));
        }
    
protected voidresetFields()
Reset all the fields that are not needed after instantiation.

        super.resetFields();
        setQuery(null);
    
protected voidsetQuery(oracle.toplink.essentials.queryframework.ReadQuery theQuery)
Set the query.

        query = theQuery;