blob: fd527fc43a4b01500585d5ab1dbd3211ec594966 [file] [log] [blame]
/*
* 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.testing.tests.unitofwork;
import java.util.Vector;
import org.eclipse.persistence.descriptors.ClassDescriptor;
import org.eclipse.persistence.internal.sessions.AbstractSession;
import org.eclipse.persistence.internal.sessions.IsolatedClientSession;
import org.eclipse.persistence.queries.DataModifyQuery;
import org.eclipse.persistence.sessions.remote.RemoteSession;
import org.eclipse.persistence.sessions.SessionEvent;
import org.eclipse.persistence.sessions.SessionEventAdapter;
import org.eclipse.persistence.testing.framework.TestErrorException;
import org.eclipse.persistence.testing.framework.TestProblemException;
import org.eclipse.persistence.testing.framework.TestWarningException;
import org.eclipse.persistence.testing.models.employee.domain.Employee;
/*
* Test for bug 4211104 Where query executed in UOW event (during trans) prevents UOW
* from commiting the transaction Resulting in a rollback.
*/
public class CommitAfterExecuteModifyQueryDuringTransTest extends org.eclipse.persistence.testing.framework.AutoVerifyTestCase {
Employee originalEmployee;
Employee cachedEmployee = null;
DataModifyQuery dataModifyQuery = null;
org.eclipse.persistence.sessions.UnitOfWork uow = null;
String employeesNewFirstName = "";
Object initialVersionField = null;
public CommitAfterExecuteModifyQueryDuringTransTest() {
setDescription("Test for successful UOW commit with DataModifyQuery being executed from an event during the transaction");
}
/**
* Test makes modifications that is not wrapped in a transaction..
*/
@Override
public void setup() {
if (getSession() instanceof RemoteSession) {
throw new TestWarningException("test will not run on RemoteSession - it uses events");
}
//employee to be modified - needed for reset.
cachedEmployee = (Employee)getSession().readObject(Employee.class);
ClassDescriptor descriptor = getSession().getDescriptor(this.cachedEmployee );
if (descriptor.isProtectedIsolation() && descriptor.shouldIsolateProtectedObjectsInUnitOfWork() && getSession() instanceof IsolatedClientSession){
// this will have read a version of the protected Entity into the Isolated Cache even though the test wants to isolated to UOW
//replace with actual shared cache version
this.cachedEmployee = (Employee) ((AbstractSession)getSession()).getParentIdentityMapSession(descriptor, false, true).getIdentityMapAccessor().getFromIdentityMap(this.cachedEmployee);
}
originalEmployee = (Employee)getSession().copy(cachedEmployee);
employeesNewFirstName = "formerlyKnownAs";
initialVersionField = getSession().getIdentityMapAccessor().getWriteLockValue(cachedEmployee);
//query to be executed more than once
dataModifyQuery =
new DataModifyQuery("UPDATE EMPLOYEE SET F_NAME = #F_NAME, VERSION = #VERSION WHERE L_NAME = #L_NAME");
dataModifyQuery.addArgument("F_NAME");
dataModifyQuery.addArgument("VERSION");
dataModifyQuery.addArgument("L_NAME");
}
/**
* Test makes modifications that is not wrapped in a transaction..
* so we have to reset our change
*/
@Override
public void reset() {
Vector myV = new Vector();
myV.addElement(originalEmployee.firstName);
myV.addElement(initialVersionField);
myV.addElement(originalEmployee.lastName);
try {
getSession().getIdentityMapAccessor().initializeAllIdentityMaps();
getSession().executeQuery(dataModifyQuery, myV);
} catch (Exception internalException) {
throw new TestProblemException("Test case may not have cleaned up correctly affecting other tests",
internalException);
}
}
@Override
public void test() {
uow = getSession().acquireUnitOfWork();
uow.getEventManager().addListener(new SessionEventAdapter() {
@Override
public void prepareUnitOfWork(SessionEvent event) {
Vector myV = new Vector();
myV.addElement(employeesNewFirstName);
myV.addElement(initialVersionField);
myV.addElement(originalEmployee.lastName);
uow.executeQuery(dataModifyQuery, myV);
}
});
Employee temp = (Employee)uow.registerObject(cachedEmployee);
temp.firstName = "tempFirstName";
//no exceptions are expected, though transaction should not be commited if test fails:
uow.commit();
cachedEmployee = (Employee)getSession().refreshObject(cachedEmployee);
}
@Override
public void verify() {
if (!employeesNewFirstName.equals(cachedEmployee.firstName)) {
throw new TestErrorException("UOW was not commited when non-selecting SQL was issued during transaction. Emp First name was not updated");
}
}
}