Search in sources :

Example 16 with DeleteObjectQuery

use of org.eclipse.persistence.queries.DeleteObjectQuery in project eclipselink by eclipse-ee4j.

the class AggregateCollectionMapping method preDelete.

/**
 * INTERNAL:
 * Delete privately owned parts
 */
@Override
public void preDelete(DeleteObjectQuery query) throws DatabaseException, OptimisticLockException {
    if (isReadOnly()) {
        return;
    }
    AbstractSession session = query.getSession();
    // If privately owned parts have their privately own parts, delete those one by one
    // else delete everything in one shot.
    int index = 0;
    if (mustDeleteReferenceObjectsOneByOne()) {
        Object objects = getRealCollectionAttributeValueFromObject(query.getObject(), query.getSession());
        ContainerPolicy cp = getContainerPolicy();
        if (this.isCascadeOnDeleteSetOnDatabase && session.isUnitOfWork()) {
            for (Object iterator = cp.iteratorFor(objects); cp.hasNext(iterator); ) {
                Object wrappedObject = cp.nextEntry(iterator, session);
                Object object = cp.unwrapIteratorResult(wrappedObject);
                ((UnitOfWorkImpl) session).getCascadeDeleteObjects().add(object);
            }
        }
        for (Object iter = cp.iteratorFor(objects); cp.hasNext(iter); ) {
            Object wrappedObject = cp.nextEntry(iter, session);
            DeleteObjectQuery deleteQuery = new DeleteObjectQuery();
            deleteQuery.setIsExecutionClone(true);
            Map extraData = null;
            if (this.listOrderField != null) {
                extraData = new DatabaseRecord(1);
                extraData.put(this.listOrderField, index++);
            }
            prepareModifyQueryForDelete(query, deleteQuery, wrappedObject, extraData);
            session.executeQuery(deleteQuery, deleteQuery.getTranslationRow());
            cp.propogatePreDelete(query, wrappedObject);
        }
        if (!session.isUnitOfWork()) {
            // This deletes any objects on the database, as the collection in memory may has been changed.
            // This is not required for unit of work, as the update would have already deleted these objects,
            // and the backup copy will include the same objects causing double deletes.
            verifyDeleteForUpdate(query);
        }
    } else {
        deleteAll(query, session);
    }
}
Also used : ContainerPolicy(org.eclipse.persistence.internal.queries.ContainerPolicy) DatabaseRecord(org.eclipse.persistence.sessions.DatabaseRecord) DeleteObjectQuery(org.eclipse.persistence.queries.DeleteObjectQuery) Map(java.util.Map) HashMap(java.util.HashMap) TreeMap(java.util.TreeMap) AbstractSession(org.eclipse.persistence.internal.sessions.AbstractSession)

Example 17 with DeleteObjectQuery

use of org.eclipse.persistence.queries.DeleteObjectQuery in project eclipselink by eclipse-ee4j.

the class ExpressionQueryMechanism method buildDeleteStatement.

/**
 * Return the appropriate delete statement
 */
protected SQLDeleteStatement buildDeleteStatement(DatabaseTable table) {
    SQLDeleteStatement deleteStatement = new SQLDeleteStatement();
    Expression whereClause;
    whereClause = getDescriptor().getObjectBuilder().buildDeleteExpression(table, getTranslationRow(), ((DeleteObjectQuery) getQuery()).usesOptimisticLocking());
    deleteStatement.setWhereClause(whereClause);
    deleteStatement.setTable(table);
    deleteStatement.setTranslationRow(getTranslationRow());
    deleteStatement.setHintString(getQuery().getHintString());
    return deleteStatement;
}
Also used : SQLDeleteStatement(org.eclipse.persistence.internal.expressions.SQLDeleteStatement) FieldExpression(org.eclipse.persistence.internal.expressions.FieldExpression) ConstantExpression(org.eclipse.persistence.internal.expressions.ConstantExpression) QueryKeyExpression(org.eclipse.persistence.internal.expressions.QueryKeyExpression) ParameterExpression(org.eclipse.persistence.internal.expressions.ParameterExpression) ObjectExpression(org.eclipse.persistence.internal.expressions.ObjectExpression) DataExpression(org.eclipse.persistence.internal.expressions.DataExpression) Expression(org.eclipse.persistence.expressions.Expression) DeleteObjectQuery(org.eclipse.persistence.queries.DeleteObjectQuery)

Example 18 with DeleteObjectQuery

use of org.eclipse.persistence.queries.DeleteObjectQuery in project eclipselink by eclipse-ee4j.

the class DirectCollectionMapping method postUpdateWithChangeSetListOrder.

/**
 * INTERNAL:
 * Update private owned part.
 */
protected void postUpdateWithChangeSetListOrder(WriteObjectQuery writeQuery) throws DatabaseException {
    ObjectChangeSet changeSet = writeQuery.getObjectChangeSet();
    DirectCollectionChangeRecord changeRecord = (DirectCollectionChangeRecord) changeSet.getChangesForAttributeNamed(this.getAttributeName());
    if (changeRecord == null) {
        return;
    }
    for (int index = 0; index < getReferenceKeyFields().size(); index++) {
        DatabaseField referenceKey = getReferenceKeyFields().get(index);
        DatabaseField sourceKey = getSourceKeyFields().get(index);
        Object sourceKeyValue = writeQuery.getTranslationRow().get(sourceKey);
        writeQuery.getTranslationRow().put(referenceKey, sourceKeyValue);
    }
    boolean shouldRepairOrder = false;
    if (changeRecord.getLatestCollection() instanceof IndirectList) {
        shouldRepairOrder = ((IndirectList) changeRecord.getLatestCollection()).isListOrderBrokenInDb();
    }
    if (shouldRepairOrder) {
        // delete all members of collection
        DeleteObjectQuery deleteQuery = new DeleteObjectQuery();
        deleteQuery.setObject(writeQuery.getObject());
        deleteQuery.setSession(writeQuery.getSession());
        deleteQuery.setTranslationRow(writeQuery.getTranslationRow());
        // Hey I might actually want to use an inner class here... ok array for now.
        Object[] eventDeleteAll = new Object[2];
        eventDeleteAll[0] = DeleteAll;
        eventDeleteAll[1] = deleteQuery;
        writeQuery.getSession().getCommitManager().addDataModificationEvent(this, eventDeleteAll);
        // re-insert them back
        for (int i = 0; i < ((List) changeRecord.getLatestCollection()).size(); i++) {
            Object value = ((List) changeRecord.getLatestCollection()).get(i);
            value = getFieldValue(value, writeQuery.getSession());
            AbstractRecord insertRow = writeQuery.getTranslationRow().clone();
            insertRow.add(getDirectField(), value);
            insertRow.add(this.listOrderField, i);
            // Hey I might actually want to use an inner class here... ok array for now.
            Object[] event = new Object[3];
            event[0] = Insert;
            event[1] = getInsertQuery();
            event[2] = insertRow;
            writeQuery.getSession().getCommitManager().addDataModificationEvent(this, event);
        }
        ((IndirectList) changeRecord.getLatestCollection()).setIsListOrderBrokenInDb(false);
        changeRecord.setOrderHasBeenRepaired(true);
        return;
    }
    if (changeRecord.getChangedIndexes() == null) {
        compareListsForChange((List) changeRecord.getOriginalCollection(), (List) changeRecord.getLatestCollection(), changeRecord, writeQuery.getSession());
    }
    Iterator<Map.Entry<Object, Set[]>> it = changeRecord.getChangedIndexes().entrySet().iterator();
    while (it.hasNext()) {
        Map.Entry<Object, Set[]> entry = it.next();
        Object value = entry.getKey();
        if (getValueConverter() != null) {
            value = getValueConverter().convertObjectValueToDataValue(value, writeQuery.getSession());
        }
        Set[] indexes = entry.getValue();
        Set indexesBefore = indexes[0];
        Set indexesAfter = indexes[1];
        if (indexesAfter == null) {
            // All copies of the target object deleted - don't need to verify order field contents.
            AbstractRecord deleteRow = writeQuery.getTranslationRow().clone();
            // Hey I might actually want to use an inner class here... ok array for now.
            Object[] event = new Object[3];
            event[0] = Delete;
            if (value == null) {
                // Bug 306075 - for deleting a null value from a collection
                event[1] = getDeleteNullQuery();
            } else {
                deleteRow.add(getDirectField(), value);
                event[1] = getDeleteQuery();
            }
            event[2] = deleteRow;
            writeQuery.getSession().getCommitManager().addDataModificationEvent(this, event);
        } else if (indexesAfter.isEmpty()) {
            // Some copies of the target objects should be deleted, some left in the db
            Iterator<Integer> itBefore = indexesBefore.iterator();
            while (itBefore.hasNext()) {
                AbstractRecord deleteAtIndexRow = writeQuery.getTranslationRow().clone();
                deleteAtIndexRow.add(getDirectField(), value);
                deleteAtIndexRow.add(this.listOrderField, itBefore.next());
                // Hey I might actually want to use an inner class here... ok array for now.
                Object[] event = new Object[3];
                event[0] = DeleteAtIndex;
                event[1] = deleteAtIndexQuery;
                event[2] = deleteAtIndexRow;
                writeQuery.getSession().getCommitManager().addDataModificationEvent(this, event);
            }
        } else {
            if (indexesBefore == null || indexesBefore.isEmpty()) {
                // insert the object for each index in indexesAfter
                Iterator<Integer> itAfter = indexesAfter.iterator();
                while (itAfter.hasNext()) {
                    AbstractRecord insertRow = writeQuery.getTranslationRow().clone();
                    insertRow.add(getDirectField(), value);
                    insertRow.add(this.listOrderField, itAfter.next());
                    // Hey I might actually want to use an inner class here... ok array for now.
                    Object[] event = new Object[3];
                    event[0] = Insert;
                    event[1] = getInsertQuery();
                    event[2] = insertRow;
                    writeQuery.getSession().getCommitManager().addDataModificationEvent(this, event);
                }
            } else {
                Iterator<Integer> itBefore = indexesBefore.iterator();
                Iterator<Integer> itAfter = indexesAfter.iterator();
                while (itBefore.hasNext() || itAfter.hasNext()) {
                    if (itBefore.hasNext()) {
                        if (itAfter.hasNext()) {
                            // update the object changing index from indexBefore to indexAfter
                            AbstractRecord updateAtIndexRow = writeQuery.getTranslationRow().clone();
                            updateAtIndexRow.add(getDirectField(), value);
                            updateAtIndexRow.add(this.listOrderField, itBefore.next());
                            // Hey I might actually want to use an inner class here... ok array for now.
                            Object[] event = new Object[4];
                            event[0] = UpdateAtIndex;
                            event[1] = updateAtIndexQuery;
                            event[2] = updateAtIndexRow;
                            DatabaseRecord modifyRow = new DatabaseRecord(1);
                            modifyRow.add(this.listOrderField, itAfter.next());
                            event[3] = modifyRow;
                            writeQuery.getSession().getCommitManager().addDataModificationEvent(this, event);
                        } else {
                            // delete the object at indexBefore
                            AbstractRecord deleteAtIndexRow = writeQuery.getTranslationRow().clone();
                            deleteAtIndexRow.add(getDirectField(), value);
                            deleteAtIndexRow.add(this.listOrderField, itBefore.next());
                            // Hey I might actually want to use an inner class here... ok array for now.
                            Object[] event = new Object[3];
                            event[0] = DeleteAtIndex;
                            event[1] = deleteAtIndexQuery;
                            event[2] = deleteAtIndexRow;
                            writeQuery.getSession().getCommitManager().addDataModificationEvent(this, event);
                        }
                    } else {
                        // itAfter.hasNext() must be true
                        // insert the object at indexAfter
                        AbstractRecord insertRow = writeQuery.getTranslationRow().clone();
                        insertRow.add(getDirectField(), value);
                        insertRow.add(this.listOrderField, itAfter.next());
                        // Hey I might actually want to use an inner class here... ok array for now.
                        Object[] event = new Object[3];
                        event[0] = Insert;
                        event[1] = getInsertQuery();
                        event[2] = insertRow;
                        writeQuery.getSession().getCommitManager().addDataModificationEvent(this, event);
                    }
                }
            }
        }
    }
}
Also used : ObjectChangeSet(org.eclipse.persistence.internal.sessions.ObjectChangeSet) Set(java.util.Set) HashSet(java.util.HashSet) DatabaseRecord(org.eclipse.persistence.sessions.DatabaseRecord) ObjectChangeSet(org.eclipse.persistence.internal.sessions.ObjectChangeSet) DeleteObjectQuery(org.eclipse.persistence.queries.DeleteObjectQuery) AbstractRecord(org.eclipse.persistence.internal.sessions.AbstractRecord) IndirectList(org.eclipse.persistence.indirection.IndirectList) DatabaseField(org.eclipse.persistence.internal.helper.DatabaseField) Iterator(java.util.Iterator) DescriptorIterator(org.eclipse.persistence.internal.descriptors.DescriptorIterator) DirectCollectionChangeRecord(org.eclipse.persistence.internal.sessions.DirectCollectionChangeRecord) List(java.util.List) IndirectList(org.eclipse.persistence.indirection.IndirectList) ArrayList(java.util.ArrayList) Map(java.util.Map) IdentityHashMap(java.util.IdentityHashMap) HashMap(java.util.HashMap)

Example 19 with DeleteObjectQuery

use of org.eclipse.persistence.queries.DeleteObjectQuery in project eclipselink by eclipse-ee4j.

the class ObjectReferenceMapping method preDelete.

/**
 * INTERNAL:
 * Delete privately owned parts
 */
@Override
public void preDelete(DeleteObjectQuery query) throws DatabaseException, OptimisticLockException {
    // Deletion takes place according the the cascading policy
    if (!shouldObjectModifyCascadeToParts(query)) {
        return;
    }
    AbstractSession session = query.getSession();
    // Get the privately owned parts.
    Object objectInMemory = getRealAttributeValueFromObject(query.getObject(), session);
    Object objectFromDatabase = null;
    // Because the value in memory may have been changed we check the previous value or database value.
    objectFromDatabase = readPrivateOwnedForObject(query);
    // If the value was changed, both values must be deleted (uow will have inserted the new one).
    if ((objectFromDatabase != null) && (objectFromDatabase != objectInMemory)) {
        // Also check pk as may not be maintaining identity.
        Object keyForObjectInMemory = null;
        Object keyForObjectInDatabase = getPrimaryKeyForObject(objectFromDatabase, session);
        if (objectInMemory != null) {
            keyForObjectInMemory = getPrimaryKeyForObject(objectInMemory, session);
        }
        if ((keyForObjectInMemory == null) || !keyForObjectInDatabase.equals(keyForObjectInMemory)) {
            if (this.isCascadeOnDeleteSetOnDatabase && !hasRelationTableMechanism() && session.isUnitOfWork()) {
                ((UnitOfWorkImpl) session).getCascadeDeleteObjects().add(objectFromDatabase);
            }
            DeleteObjectQuery deleteQuery = new DeleteObjectQuery();
            deleteQuery.setIsExecutionClone(true);
            deleteQuery.setObject(objectFromDatabase);
            deleteQuery.setCascadePolicy(query.getCascadePolicy());
            session.executeQuery(deleteQuery);
        }
    }
    if (!isForeignKeyRelationship()) {
        if (objectInMemory != null) {
            if (this.isCascadeOnDeleteSetOnDatabase && !hasRelationTableMechanism() && session.isUnitOfWork()) {
                ((UnitOfWorkImpl) session).getCascadeDeleteObjects().add(objectInMemory);
            }
            // PERF: Avoid query execution if already deleted.
            if (session.getCommitManager().isCommitCompletedInPostOrIgnore(objectInMemory)) {
                return;
            }
            DeleteObjectQuery deleteQuery = new DeleteObjectQuery();
            deleteQuery.setIsExecutionClone(true);
            deleteQuery.setObject(objectInMemory);
            deleteQuery.setCascadePolicy(query.getCascadePolicy());
            session.executeQuery(deleteQuery);
        }
    } else {
        // The actual deletion of part takes place in postDeleteForObjectUsing(...).
        if (objectInMemory != null) {
            query.setProperty(this, objectInMemory);
        }
    }
}
Also used : DeleteObjectQuery(org.eclipse.persistence.queries.DeleteObjectQuery) AbstractSession(org.eclipse.persistence.internal.sessions.AbstractSession)

Example 20 with DeleteObjectQuery

use of org.eclipse.persistence.queries.DeleteObjectQuery in project eclipselink by eclipse-ee4j.

the class StoredProcedureGenerator method generateDeleteStoredProcedure.

/**
 * INTERNAL: Generates the delete stored procedure for this descriptor
 */
protected StoredProcedureDefinition generateDeleteStoredProcedure(ClassDescriptor descriptor) {
    DeleteObjectQuery deleteQuery = new DeleteObjectQuery();
    deleteQuery.setDescriptor(descriptor);
    deleteQuery.setModifyRow(new DatabaseRecord());
    return this.generateObjectStoredProcedure(deleteQuery, descriptor.getPrimaryKeyFields(), "DEL_");
}
Also used : DatabaseRecord(org.eclipse.persistence.sessions.DatabaseRecord) DeleteObjectQuery(org.eclipse.persistence.queries.DeleteObjectQuery)

Aggregations

DeleteObjectQuery (org.eclipse.persistence.queries.DeleteObjectQuery)20 DatabaseRecord (org.eclipse.persistence.sessions.DatabaseRecord)6 ContainerPolicy (org.eclipse.persistence.internal.queries.ContainerPolicy)5 AbstractSession (org.eclipse.persistence.internal.sessions.AbstractSession)4 ArrayList (java.util.ArrayList)2 HashMap (java.util.HashMap)2 Iterator (java.util.Iterator)2 List (java.util.List)2 Map (java.util.Map)2 ClassDescriptor (org.eclipse.persistence.descriptors.ClassDescriptor)2 DescriptorIterator (org.eclipse.persistence.internal.descriptors.DescriptorIterator)2 DatabaseField (org.eclipse.persistence.internal.helper.DatabaseField)2 ObjectChangeSet (org.eclipse.persistence.internal.sessions.ObjectChangeSet)2 HashSet (java.util.HashSet)1 IdentityHashMap (java.util.IdentityHashMap)1 Set (java.util.Set)1 TreeMap (java.util.TreeMap)1 Vector (java.util.Vector)1 Expression (org.eclipse.persistence.expressions.Expression)1 IndirectList (org.eclipse.persistence.indirection.IndirectList)1