org.eclipse.persistence.queries.DeleteObjectQuery Maven / Gradle / Ivy
Show all versions of eclipselink Show documentation
/*
* Copyright (c) 1998, 2021 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.queries;
import java.util.Set;
import org.eclipse.persistence.internal.sessions.AbstractRecord;
import org.eclipse.persistence.internal.sessions.AbstractSession;
import org.eclipse.persistence.internal.sessions.CommitManager;
import org.eclipse.persistence.internal.sessions.UnitOfWorkImpl;
import org.eclipse.persistence.mappings.DatabaseMapping.WriteType;
import org.eclipse.persistence.exceptions.*;
import org.eclipse.persistence.descriptors.ClassDescriptor;
import org.eclipse.persistence.descriptors.DescriptorEvent;
import org.eclipse.persistence.descriptors.DescriptorEventManager;
import org.eclipse.persistence.descriptors.DescriptorQueryManager;
import org.eclipse.persistence.descriptors.FetchGroupManager;
import org.eclipse.persistence.tools.profiler.QueryMonitor;
/**
* Purpose: Used for deleting objects.
*
*
Responsibilities:
* Extract primary key from object and delete it.
*
* @author Yvon Lavoie
* @since TOPLink/Java 1.0
*/
public class DeleteObjectQuery extends ObjectLevelModifyQuery {
/** PERF: By default only the translation row is used for deletes, the full row can be requested for custom deletes. */
protected boolean isFullRowRequired = false;
/** Indicates whether the query should use optimistic locking. */
protected boolean usesOptimisticLocking;
public DeleteObjectQuery() {
super();
}
public DeleteObjectQuery(Object objectToDelete) {
this();
setObject(objectToDelete);
}
public DeleteObjectQuery(Call call) {
this();
setCall(call);
}
/**
* ADVANCED:
* Return if the full row is required by the delete query.
* This can be set on custom delete queries if more than the objects primary key and version is required.
*/
public boolean isFullRowRequired()
{
return isFullRowRequired;
}
/**
* ADVANCED:
* Set if the full row is required by the delete query.
* This can be set on custom delete queries if more than the objects primary key and version is required.
*/
public void setIsFullRowRequired(boolean isFullRowRequired)
{
this.isFullRowRequired = isFullRowRequired;
}
/**
* INTERNAL:
* Check to see if a custom query should be used for this query.
* This is done before the query is copied and prepared/executed.
* null means there is none.
*/
@Override
protected DatabaseQuery checkForCustomQuery(AbstractSession session, AbstractRecord translationRow) {
checkDescriptor(session);
// check if user defined a custom query
DescriptorQueryManager queryManager = this.descriptor.getQueryManager();
if ((!isCallQuery())// this is not a hand-coded (custom SQL, SDK etc.) call
&& (!isUserDefined())// and this is not a user-defined query (in the query manager)
&& queryManager.hasDeleteQuery()) {// and there is a user-defined query (in the query manager)
return queryManager.getDeleteQuery();
}
return null;
}
/**
* INTERNAL:
* Code was moved from UnitOfWork.internalExecuteQuery
*
*/
@Override
protected Object executeInUnitOfWorkObjectLevelModifyQuery(UnitOfWorkImpl unitOfWork, AbstractRecord translationRow) throws DatabaseException, OptimisticLockException {
Object result = unitOfWork.processDeleteObjectQuery(this);
if (result != null) {
// if the above method returned something then the unit of work
//was not writing so the object has been stored to delete later
//so return the object. See the above method for the cases
//where this object will be returned.
return result;
}
return super.executeInUnitOfWorkObjectLevelModifyQuery(unitOfWork, translationRow);
}
/**
* INTERNAL:
* Returns the specific default redirector for this query type. There are numerous default query redirectors.
* See ClassDescriptor for their types.
*/
@Override
protected QueryRedirector getDefaultRedirector(){
return descriptor.getDefaultDeleteObjectQueryRedirector();
}
/**
* INTERNAL:
* Perform the work to delete an object.
* @return object - the object being deleted.
*/
@Override
public Object executeDatabaseQuery() throws DatabaseException, OptimisticLockException {
AbstractSession session = getSession();
CommitManager commitManager = session.getCommitManager();
Object object = getObject();
boolean isUnitOfWork = session.isUnitOfWork();
try {
// Check if the object has already been deleted, then no work is required.
if (commitManager.isCommitCompletedInPostOrIgnore(object)) {
return object;
}
ClassDescriptor descriptor = this.descriptor;
// Check whether the object is already being deleted,
// if it is, then there is a cycle, and the foreign keys must be nulled.
if (commitManager.isCommitInPreModify(object)) {
if (!commitManager.isShallowCommitted(object)) {
getQueryMechanism().updateForeignKeyFieldBeforeDelete();
if ((descriptor.getHistoryPolicy() != null) && descriptor.getHistoryPolicy().shouldHandleWrites()) {
descriptor.getHistoryPolicy().postUpdate(this);
}
commitManager.markShallowCommit(object);
}
return object;
}
commitManager.markPreModifyCommitInProgress(getObject());
if (!isUnitOfWork) {
session.beginTransaction();
}
DescriptorEventManager eventManager = descriptor.getEventManager();
// PERF: Avoid events if no listeners.
if (eventManager.hasAnyEventListeners()) {
// Need to run pre-delete selector if available
eventManager.executeEvent(new DescriptorEvent(DescriptorEventManager.PreDeleteEvent, this));
}
// Verify if deep shallow modify is turned on
if (shouldCascadeParts()) {
descriptor.getQueryManager().preDelete(this);
}
// Check for deletion dependencies.
if (isUnitOfWork) {
Set