Search in sources :

Example 51 with AbstractSession

use of org.eclipse.persistence.internal.sessions.AbstractSession in project eclipselink by eclipse-ee4j.

the class DatasourceCallQueryMechanism method updateObject.

/**
 * Update the object.  Assume the call is correct.
 * @exception  DatabaseException - an error has occurred on the database.
 * @return the row count.
 */
@Override
public Integer updateObject() throws DatabaseException {
    ClassDescriptor descriptor = getDescriptor();
    Collection returnFields = null;
    if (descriptor.getReturnFieldsToMergeUpdate() != null) {
        returnFields = descriptor.getReturnFieldsToMergeUpdate();
    }
    Integer returnedRowCount = null;
    if (hasMultipleCalls()) {
        int size = this.calls.size();
        for (int index = 0; index < size; index++) {
            DatasourceCall databseCall = (DatasourceCall) this.calls.get(index);
            if ((index > 0) && isExpressionQueryMechanism() && this.query.shouldCascadeOnlyDependentParts() && !descriptor.hasMultipleTableConstraintDependecy() && this.query.getSession().getProject().allowSQLDeferral()) {
                DatabaseTable table = descriptor.getMultipleTableInsertOrder().get(index);
                this.query.getSession().getCommitManager().addDeferredCall(table, databseCall, this);
            } else {
                Object result = executeCall(databseCall);
                // Set the return row if one was returned (Postgres).
                Integer rowCount;
                if (result instanceof AbstractRecord) {
                    this.query.setProperty("output", result);
                    rowCount = 1;
                } else {
                    rowCount = (Integer) result;
                }
                if ((index == 0) || (rowCount <= 0)) {
                    // Row count returned must be from first table or zero if any are zero.
                    returnedRowCount = rowCount;
                }
                if (returnFields != null) {
                    updateObjectAndRowWithReturnRow(returnFields, false);
                }
            }
        }
    } else {
        Object result = executeCall();
        // Set the return row if one was returned (Postgres).
        if (result instanceof AbstractRecord) {
            this.query.setProperty("output", result);
            returnedRowCount = 1;
        } else {
            returnedRowCount = (Integer) result;
        }
        if (returnFields != null) {
            updateObjectAndRowWithReturnRow(returnFields, false);
        }
    }
    // Oracle thin driver handles LOB differently. During the insert, empty lob would be
    // insert first, and then the LOb locator is retrieved and LOB data are written through
    // the locator.
    // 
    // Bug 2804663 - LOBValueWriter is no longer a singleton, so we execute any deferred
    // select calls through the DatabaseAccessor which holds the writer instance
    // 
    // Building of SELECT statements is no longer done in DatabaseAccessor.basicExecuteCall
    // because DatabaseCall.isUpdateCall() can't recognize update in case StoredProcedureCall
    // is used.
    AbstractSession executionSession = this.query.getExecutionSession();
    for (Accessor accessor : executionSession.getAccessors()) {
        accessor.flushSelectCalls(executionSession);
    }
    return returnedRowCount;
}
Also used : ClassDescriptor(org.eclipse.persistence.descriptors.ClassDescriptor) AbstractRecord(org.eclipse.persistence.internal.sessions.AbstractRecord) Collection(java.util.Collection) DatabaseTable(org.eclipse.persistence.internal.helper.DatabaseTable) DatasourceCall(org.eclipse.persistence.internal.databaseaccess.DatasourceCall) Accessor(org.eclipse.persistence.internal.databaseaccess.Accessor) AbstractSession(org.eclipse.persistence.internal.sessions.AbstractSession)

Example 52 with AbstractSession

use of org.eclipse.persistence.internal.sessions.AbstractSession in project eclipselink by eclipse-ee4j.

the class DatasourceCallQueryMechanism method prepareCall.

/**
 * INTERNAL:
 * This is different from 'prepareForExecution' in that this is called on the original query,
 * and the other is called on the copy of the query.
 * This query is copied for concurrency so this prepare can only setup things that
 * will apply to any future execution of this query.
 */
public void prepareCall() throws QueryException {
    DatabaseQuery query = getQuery();
    AbstractSession executionSession = query.getExecutionSession();
    if (hasMultipleCalls()) {
        for (DatasourceCall call : (List<DatasourceCall>) getCalls()) {
            call.prepare(executionSession);
        }
    } else if (getCall() != null) {
        getCall().prepare(executionSession);
    }
}
Also used : DatabaseQuery(org.eclipse.persistence.queries.DatabaseQuery) List(java.util.List) DatasourceCall(org.eclipse.persistence.internal.databaseaccess.DatasourceCall) AbstractSession(org.eclipse.persistence.internal.sessions.AbstractSession)

Example 53 with AbstractSession

use of org.eclipse.persistence.internal.sessions.AbstractSession in project eclipselink by eclipse-ee4j.

the class DatasourceCallQueryMechanism method updateForeignKeyFieldAfterInsert.

/**
 * Update the foreign key fields when resolving a bi-directional reference in a UOW.
 * This is rare to occur for non-relational, however if it does each of the calls must be re-executed.
 */
@Override
protected void updateForeignKeyFieldAfterInsert(WriteObjectQuery writeQuery) {
    writeQuery.setModifyRow(this.getDescriptor().getObjectBuilder().buildRow(writeQuery.getObject(), this.getSession(), WriteType.INSERT));
    // For CR 2923 must move to session we will execute call on now
    // so correct DatasourcePlatform used by translate.
    AbstractSession sessionToUse = this.query.getExecutionSession();
    // yes - this is a bit ugly...
    Vector calls = ((DatasourceCallQueryMechanism) this.getDescriptor().getQueryManager().getUpdateQuery().getQueryMechanism()).getCalls();
    for (Enumeration stream = calls.elements(); stream.hasMoreElements(); ) {
        DatasourceCall call = (DatasourceCall) ((DatasourceCall) stream.nextElement()).clone();
        call.setQuery(writeQuery);
        sessionToUse.executeCall(call, this.getTranslationRow(), writeQuery);
    }
}
Also used : Enumeration(java.util.Enumeration) Vector(java.util.Vector) DatasourceCall(org.eclipse.persistence.internal.databaseaccess.DatasourceCall) AbstractSession(org.eclipse.persistence.internal.sessions.AbstractSession)

Example 54 with AbstractSession

use of org.eclipse.persistence.internal.sessions.AbstractSession in project eclipselink by eclipse-ee4j.

the class JoinedAttributeManager method processDataResults.

/**
 * Process the data-results for joined data for a 1-m join.
 * This allows incremental processing for a cursor.
 */
public AbstractRecord processDataResults(AbstractRecord row, Cursor cursor, boolean forward) {
    if (this.dataResultsByPrimaryKey == null) {
        this.dataResultsByPrimaryKey = new HashMap<>();
    }
    AbstractRecord parentRow = row;
    List<AbstractRecord> childRows = new ArrayList<>();
    childRows.add(row);
    int parentIndex = getParentResultIndex();
    // Must adjust for the parent index to ensure the correct pk is extracted.
    Vector<DatabaseField> trimedFields = new NonSynchronizedSubVector<>(row.getFields(), parentIndex, row.size());
    if (parentIndex > 0) {
        Vector trimedValues = new NonSynchronizedSubVector(row.getValues(), parentIndex, row.size());
        parentRow = new DatabaseRecord(trimedFields, trimedValues);
    }
    ObjectBuilder builder = getDescriptor().getObjectBuilder();
    AbstractSession session = cursor.getExecutionSession();
    // Extract the primary key of the source object, to filter only the joined rows for that object.
    Object sourceKey = builder.extractPrimaryKeyFromRow(parentRow, session);
    AbstractRecord extraRow = null;
    while (true) {
        AbstractRecord nextRow = null;
        if (forward) {
            nextRow = cursor.getAccessor().cursorRetrieveNextRow(cursor.getFields(), cursor.getResultSet(), session);
        } else {
            nextRow = cursor.getAccessor().cursorRetrievePreviousRow(cursor.getFields(), cursor.getResultSet(), session);
        }
        if (nextRow == null) {
            break;
        }
        AbstractRecord nextParentRow = nextRow;
        if (parentIndex > 0) {
            Vector trimedValues = new NonSynchronizedSubVector(nextParentRow.getValues(), parentIndex, nextParentRow.size());
            nextParentRow = new DatabaseRecord(trimedFields, trimedValues);
        }
        // Extract the primary key of the source object, to filter only the joined rows for that object.
        Object nextKey = builder.extractPrimaryKeyFromRow(nextParentRow, session);
        if ((sourceKey != null) && sourceKey.equals(nextKey)) {
            childRows.add(nextRow);
        } else {
            extraRow = nextRow;
            break;
        }
    }
    this.dataResultsByPrimaryKey.put(sourceKey, childRows);
    return extraRow;
}
Also used : DatabaseRecord(org.eclipse.persistence.sessions.DatabaseRecord) AbstractRecord(org.eclipse.persistence.internal.sessions.AbstractRecord) ArrayList(java.util.ArrayList) ObjectBuilder(org.eclipse.persistence.internal.descriptors.ObjectBuilder) DatabaseField(org.eclipse.persistence.internal.helper.DatabaseField) NonSynchronizedSubVector(org.eclipse.persistence.internal.helper.NonSynchronizedSubVector) Vector(java.util.Vector) NonSynchronizedSubVector(org.eclipse.persistence.internal.helper.NonSynchronizedSubVector) AbstractSession(org.eclipse.persistence.internal.sessions.AbstractSession)

Example 55 with AbstractSession

use of org.eclipse.persistence.internal.sessions.AbstractSession in project eclipselink by eclipse-ee4j.

the class ArrayCollectionMappingHelper method mergeChangesIntoObjectWithOrder.

/**
 * Merge changes from the source to the target object.
 * Simply replace the entire target collection.
 */
private void mergeChangesIntoObjectWithOrder(Object target, ChangeRecord changeRecord, Object source, MergeManager mergeManager, AbstractSession targetSession) {
    ContainerPolicy cp = getContainerPolicy();
    AbstractSession session = mergeManager.getSession();
    List changes = ((EISOrderedCollectionChangeRecord) changeRecord).getNewCollection();
    Object targetCollection = cp.containerInstance(changes.size());
    for (Object changed : changes) {
        Object targetElement = buildAddedElementFromChangeSet(changed, mergeManager, targetSession);
        cp.addInto(targetElement, targetCollection, session);
    }
    // reset the attribute to allow for set method to re-morph changes if the collection is not being stored directly
    this.setRealAttributeValueInObject(target, targetCollection);
}
Also used : ContainerPolicy(org.eclipse.persistence.internal.queries.ContainerPolicy) List(java.util.List) EISOrderedCollectionChangeRecord(org.eclipse.persistence.eis.EISOrderedCollectionChangeRecord) AbstractSession(org.eclipse.persistence.internal.sessions.AbstractSession)

Aggregations

AbstractSession (org.eclipse.persistence.internal.sessions.AbstractSession)215 ClassDescriptor (org.eclipse.persistence.descriptors.ClassDescriptor)52 ContainerPolicy (org.eclipse.persistence.internal.queries.ContainerPolicy)28 ArrayList (java.util.ArrayList)26 AbstractRecord (org.eclipse.persistence.internal.sessions.AbstractRecord)26 Vector (java.util.Vector)22 DatabaseField (org.eclipse.persistence.internal.helper.DatabaseField)22 DatabaseMapping (org.eclipse.persistence.mappings.DatabaseMapping)21 EntityManager (jakarta.persistence.EntityManager)19 List (java.util.List)18 Session (org.eclipse.persistence.sessions.Session)18 JpaEntityManager (org.eclipse.persistence.jpa.JpaEntityManager)15 InvalidObject (org.eclipse.persistence.internal.helper.InvalidObject)14 UnitOfWorkImpl (org.eclipse.persistence.internal.sessions.UnitOfWorkImpl)14 HashMap (java.util.HashMap)12 Map (java.util.Map)12 Collection (java.util.Collection)11 DatabaseQuery (org.eclipse.persistence.queries.DatabaseQuery)11 SQLException (java.sql.SQLException)10 DatabaseException (org.eclipse.persistence.exceptions.DatabaseException)9