| /* |
| * 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.io.StringWriter; |
| import java.io.Writer; |
| |
| import org.eclipse.persistence.expressions.Expression; |
| import org.eclipse.persistence.expressions.ExpressionBuilder; |
| import org.eclipse.persistence.logging.SessionLog; |
| import org.eclipse.persistence.sessions.Session; |
| import org.eclipse.persistence.sessions.SessionEventListener; |
| import org.eclipse.persistence.sessions.UnitOfWork; |
| import org.eclipse.persistence.testing.tests.remote.RemoteModel; |
| import org.eclipse.persistence.testing.framework.AutoVerifyTestCase; |
| import org.eclipse.persistence.testing.framework.TestErrorException; |
| import org.eclipse.persistence.testing.framework.TestWarningException; |
| import org.eclipse.persistence.testing.models.employee.domain.Employee; |
| |
| |
| /** |
| * Test that the refresh in a unit of work does not needlessly commit changes. |
| */ |
| public class UnitOfWorkComplexRefreshTest extends AutoVerifyTestCase { |
| protected Employee dbEmployee1; |
| protected Employee dbEmployee2; |
| protected UnitOfWork uow1; |
| protected UnitOfWork uow2; |
| protected Writer oldLog; |
| protected int oldLogLevel; |
| protected StringWriter tempWriter; |
| // On some platforms (Sybase) if conn1 updates a row but hasn't yet committed transaction then |
| // reading the row through conn2 may hang. |
| // To avoid this problem the listener would decrement transaction isolation level, |
| // then reading through conn2 no longer hangs, however may result (results on Sybase) |
| // in reading of uncommitted data. |
| SessionEventListener listener; |
| |
| public UnitOfWorkComplexRefreshTest() { |
| setDescription("Test that a refreshed object in unit of work does not generate sql on commit."); |
| } |
| |
| @Override |
| public void setup() { |
| if (getSession().isClientSession()) { |
| listener = checkTransactionIsolation(); |
| } |
| |
| if (getSession().isRemoteSession() && getSession().getDatasourcePlatform().isDerby()) { |
| throw new TestWarningException("This test uses functionality that does not work over remote sessions in Apache Derby."); |
| } |
| |
| getAbstractSession().beginTransaction(); |
| uow1 = getSession().acquireUnitOfWork(); |
| uow2 = getSession().acquireUnitOfWork(); |
| |
| Expression exp = new ExpressionBuilder().get("firstName").equal("Charles"); |
| dbEmployee1 = (Employee)uow1.readObject(Employee.class, exp); |
| dbEmployee2 = (Employee)uow2.readObject(Employee.class, exp); |
| dbEmployee1.getAddress().setCity("Bobstown"); |
| } |
| |
| @Override |
| public void reset() { |
| if(getAbstractSession().isInTransaction()) { |
| getAbstractSession().rollbackTransaction(); |
| } |
| getSession().getIdentityMapAccessor().initializeAllIdentityMaps(); |
| if(listener != null) { |
| getAbstractSession().getParent().getEventManager().removeListener(listener); |
| listener = null; |
| } |
| } |
| |
| public void switchLog(Session aSession) { |
| if (aSession instanceof org.eclipse.persistence.internal.sessions.remote.RemoteUnitOfWork) { |
| aSession = RemoteModel.getServerSession(); |
| } |
| oldLog = aSession.getLog(); |
| oldLogLevel = aSession.getLogLevel(); |
| aSession.setLogLevel(SessionLog.FINE); |
| tempWriter = new StringWriter(); |
| aSession.setLog(tempWriter); |
| } |
| |
| public void switchLoggingBack(Session aSession) { |
| if (aSession.isRemoteUnitOfWork()) { |
| aSession = RemoteModel.getServerSession(); |
| } |
| aSession.setLogLevel(oldLogLevel); |
| aSession.setLog(oldLog); |
| } |
| |
| @Override |
| public void test() { |
| dbEmployee2.getAddress().setCity("Yousersville"); |
| uow2.commit(); |
| |
| uow1.refreshObject(dbEmployee1); |
| switchLog(uow1); |
| uow1.commit(); |
| switchLoggingBack(uow1); |
| } |
| |
| @Override |
| public void verify() { |
| if (dbEmployee1.getAddress().getCity().equals("Bobstown")) { |
| // The address was not properly refreshed. |
| throw new TestErrorException("The object in the unit of work was properly refreshed."); |
| } |
| |
| if (tempWriter.toString().indexOf("UPDATE ADDRESS SET CITY = 'Yousersville'") != -1) { |
| throw new TestErrorException("The second commit updated the database, but should not have, '" + |
| tempWriter.toString() + "'"); |
| } |
| } |
| } |