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

org.eclipse.persistence.internal.indirection.BatchValueHolder Maven / Gradle / Ivy

There is a newer version: 4.0.2
Show newest version
/*
 * Copyright (c) 1998, 2018 Oracle and/or its affiliates. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0 which is available at
 * http://www.eclipse.org/legal/epl-2.0,
 * or the Eclipse Distribution License v. 1.0 which is available at
 * http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
 */

// Contributors:
//     Oracle - initial API and implementation from Oracle TopLink
package org.eclipse.persistence.internal.indirection;

import org.eclipse.persistence.internal.identitymaps.CacheKey;
import org.eclipse.persistence.internal.sessions.AbstractRecord;
import org.eclipse.persistence.internal.sessions.AbstractSession;
import org.eclipse.persistence.internal.sessions.UnitOfWorkImpl;
import org.eclipse.persistence.mappings.*;
import org.eclipse.persistence.queries.*;
import org.eclipse.persistence.exceptions.*;

/**
 * BatchValueHolder is used by the mappings that use indirection when using query optimization (batch reading).
 * This value holder is different from QueryBasedValueHolder in that its value must be extracted from one of the
 * results return by the query, not the entire result.
 * The query is also shared by all other value holders within the batch and it must be ensured that the query is only
 * executed once.  Concurrency must also be maintained across all of the value holders in the batch.
 */
public class BatchValueHolder extends QueryBasedValueHolder {
    protected transient ForeignReferenceMapping mapping;
    protected transient ObjectLevelReadQuery originalQuery;
    protected transient CacheKey parentCacheKey;

    /**
     * Initialize the query-based value holder.
     * @param query The query that returns the object when executed.
     * @param row The row representation of the object.
     * @param mapping The mapping that is uses batch reading.
     */
    public BatchValueHolder(ReadQuery query, AbstractRecord row, ForeignReferenceMapping mapping, ObjectLevelReadQuery originalQuery, CacheKey parentCacheKey) {
        super(query, row, originalQuery.getSession());
        this.mapping = mapping;
        this.originalQuery = originalQuery;
        this.parentCacheKey = parentCacheKey;
    }

    protected ForeignReferenceMapping getMapping() {
        return mapping;
    }

    /**
     * Instantiate the object by having the mapping extract its value from the query.
     * Concurrency must be maintained across all of the value holders,
     * since they all share the same query, the extractResultFromBatchQuery method must be synchronized.
     */
    protected Object instantiate(AbstractSession session) throws EclipseLinkException {
        return this.mapping.extractResultFromBatchQuery(this.query, this.parentCacheKey, this.row, session, this.originalQuery);
    }

    /**
     * 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 synchronized manner. * The batch value holder must use a batch query relative to the unit of work, * as the batch is local to the unit of work. */ public Object instantiateForUnitOfWorkValueHolder(UnitOfWorkValueHolder unitOfWorkValueHolder) { UnitOfWorkImpl unitOfWork = unitOfWorkValueHolder.getUnitOfWork(); ReadQuery localQuery = unitOfWork.getBatchQueries().get(this.query); if (localQuery == null) { localQuery = (ReadQuery)this.query.clone(); unitOfWork.getBatchQueries().put(this.query, localQuery); } return this.mapping.extractResultFromBatchQuery(localQuery, this.parentCacheKey, this.row, unitOfWorkValueHolder.getUnitOfWork(), this.originalQuery); } /** * INTERNAL: * Answers if this valueholder is easy to instantiate. * @return true if getValue() won't trigger a database read. */ public boolean isEasilyInstantiated() { return this.isInstantiated; } /** * Reset all the fields that are not needed after instantiation. */ protected void resetFields() { super.resetFields(); this.mapping = null; this.originalQuery = null; } protected void setMapping(ForeignReferenceMapping mapping) { this.mapping = mapping; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy