| /* |
| * 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 org.eclipse.persistence.exceptions.*; |
| import org.eclipse.persistence.internal.sessions.UnitOfWorkImpl; |
| |
| /** |
| * <p><b>Purpose</b>: |
| * Used for inserting or updating objects |
| * WriteObjectQuery determines whether to perform a insert or an update on the database. |
| * |
| * <p><b>Responsibilities</b>: |
| * <ul> |
| * <li> Determines whether to perform a insert or an update on the database. |
| * <li> Stores object in identity map for insert if required. |
| * </ul> |
| * |
| * @author Yvon Lavoie |
| * @since TOPLink/Java 1.0 |
| */ |
| public class WriteObjectQuery extends ObjectLevelModifyQuery { |
| public WriteObjectQuery() { |
| super(); |
| } |
| |
| public WriteObjectQuery(Object objectToWrite) { |
| this(); |
| setObject(objectToWrite); |
| } |
| |
| public WriteObjectQuery(Call call) { |
| this(); |
| setCall(call); |
| } |
| |
| /** |
| * INTERNAL: |
| * Perform a does exist check to decide whether to perform an insert or update and |
| * delegate the work to the mechanism. Does exists check will also perform an |
| * optimistic lock check if required. |
| * @exception DatabaseException - an error has occurred on the database |
| * @exception OptimisticLockException - an error has occurred using the optimistic lock feature |
| * @return object - the object being written. |
| */ |
| @Override |
| public Object executeDatabaseQuery() throws DatabaseException, OptimisticLockException { |
| if (getObjectChangeSet() != null) { |
| return getQueryMechanism().executeWriteWithChangeSet(); |
| } else { |
| return getQueryMechanism().executeWrite(); |
| } |
| } |
| |
| /** |
| * INTERNAL: |
| * Perform a does exist check to decide whether to perform an insert or update and |
| * delegate the work to the mechanism. |
| */ |
| public void executeCommit() throws DatabaseException, OptimisticLockException { |
| boolean doesExist; |
| |
| if (getSession().isUnitOfWork()) { |
| doesExist = !((UnitOfWorkImpl)getSession()).isCloneNewObject(getObject()); |
| if (doesExist) { |
| doesExist = ((UnitOfWorkImpl)getSession()).isObjectRegistered(getObject()); |
| } |
| } else { |
| //Initialize does exist query |
| DoesExistQuery existQuery = (DoesExistQuery)this.descriptor.getQueryManager().getDoesExistQuery().clone(); |
| existQuery.setObject(getObject()); |
| existQuery.setPrimaryKey(getPrimaryKey()); |
| existQuery.setDescriptor(this.descriptor); |
| existQuery.setTranslationRow(getTranslationRow()); |
| |
| doesExist = (Boolean) getSession().executeQuery(existQuery); |
| } |
| |
| // Do insert of update |
| if (doesExist) { |
| // Must do an update |
| getQueryMechanism().updateObjectForWrite(); |
| } else { |
| // Must do an insert |
| getQueryMechanism().insertObjectForWrite(); |
| } |
| } |
| |
| /** |
| * INTERNAL: |
| * Perform a does exist check to decide whether to perform an insert or update and |
| * delegate the work to the mechanism. |
| */ |
| public void executeCommitWithChangeSet() throws DatabaseException, OptimisticLockException { |
| // Do insert of update |
| if (!getObjectChangeSet().isNew()) { |
| // Must do an update |
| if (!getSession().getCommitManager().isCommitInPreModify(getObject())) { |
| //If the changeSet is in the PreModify then it is in the process of being written |
| getQueryMechanism().updateObjectForWriteWithChangeSet(); |
| } |
| } else { |
| // check whether the object is already being committed - |
| // if it is and it is new, then a shallow insert must be done |
| if (getSession().getCommitManager().isCommitInPreModify(getObject())) { |
| // a shallow insert must be performed |
| this.dontCascadeParts(); |
| getQueryMechanism().insertObjectForWrite(); |
| getSession().getCommitManager().markShallowCommit(object); |
| } else { |
| // Must do an insert |
| getQueryMechanism().insertObjectForWrite(); |
| } |
| } |
| } |
| |
| /** |
| * 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.getDefaultQueryRedirector(); |
| } |
| |
| /** |
| * PUBLIC: |
| * Return if this is a write object query. |
| */ |
| @Override |
| public boolean isWriteObjectQuery() { |
| return true; |
| } |
| |
| /** |
| * INTERNAL: |
| * Prepare the receiver for execution in a session. |
| */ |
| @Override |
| public void prepareForExecution() throws QueryException { |
| super.prepareForExecution(); |
| |
| // Set the tranlation row, it may already be set in the custom query situation. |
| // PERF: Only build the translation row for updates, as inserts do not have a where clause. |
| if ((!isInsertObjectQuery()) && ((getTranslationRow() == null) || (getTranslationRow().isEmpty()))) { |
| setTranslationRow(this.descriptor.getObjectBuilder().buildRowForTranslation(getObject(), getSession())); |
| } |
| } |
| } |