/*
 * Copyright (c) 1998, 2021 Oracle and/or its affiliates. All rights reserved.
 * Copyright (c) 1998, 2021 IBM Corporation. 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
//     27/07/2010 - 2.1.1 Sabine Heider
//          304650: fix left over entity data interfering with testSetRollbackOnly
//     11/17/2010-2.2 Michael O'Brien
//       - 325605: Do not track SQL category logs in QuerySQLTracker logged at FINEST
//         testDeleteEmployee//() will fail on DB2 9.7 Universal because cascade deletes
//         of an uninstantiated collection of enums must inherently be deleted even if
//         the actual collection is empty.  DB2 warns of nothing deleted - we convert it to a FINEST log
//     01/15/2015-2.6 Mythily Parthasarathy
//       - 457480: NPE in  MethodAttributeAccessor.getAttributeValueFromObject
//     01/29/2019-3.0 Sureshkumar Balakrishnan
//       - 541873: ENTITYMANAGER.DETACH() TRIGGERS LAZY LOADING INTO THE PERSISTENCE CONTEXT
package org.eclipse.persistence.testing.tests.jpa.advanced;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.StringWriter;
import java.sql.Connection;
import java.sql.Date;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Time;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;
import java.util.Collections;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.Vector;

import jakarta.persistence.EntityExistsException;
import jakarta.persistence.EntityManager;
import jakarta.persistence.EntityManagerFactory;
import jakarta.persistence.EntityNotFoundException;
import jakarta.persistence.FlushModeType;
import jakarta.persistence.LockModeType;
import jakarta.persistence.NoResultException;
import jakarta.persistence.OptimisticLockException;
import jakarta.persistence.Persistence;
import jakarta.persistence.PersistenceException;
import jakarta.persistence.PersistenceUnitUtil;
import jakarta.persistence.PessimisticLockScope;
import jakarta.persistence.Query;
import jakarta.persistence.RollbackException;
import jakarta.persistence.TemporalType;
import jakarta.persistence.TransactionRequiredException;
import jakarta.persistence.TypedQuery;
import jakarta.persistence.spi.LoadState;
import jakarta.persistence.spi.ProviderUtil;
import javax.sql.DataSource;

import junit.framework.TestCase;
import org.eclipse.persistence.annotations.IdValidation;
import org.eclipse.persistence.config.CacheUsage;
import org.eclipse.persistence.config.CacheUsageIndirectionPolicy;
import org.eclipse.persistence.config.CascadePolicy;
import org.eclipse.persistence.config.EntityManagerProperties;
import org.eclipse.persistence.config.ExclusiveConnectionMode;
import org.eclipse.persistence.config.HintValues;
import org.eclipse.persistence.config.PersistenceUnitProperties;
import org.eclipse.persistence.config.PessimisticLock;
import org.eclipse.persistence.config.QueryHints;
import org.eclipse.persistence.config.QueryType;
import org.eclipse.persistence.config.ResultSetConcurrency;
import org.eclipse.persistence.config.ResultSetType;
import org.eclipse.persistence.config.ResultType;
import org.eclipse.persistence.config.SessionCustomizer;
import org.eclipse.persistence.config.SystemProperties;
import org.eclipse.persistence.descriptors.ClassDescriptor;
import org.eclipse.persistence.descriptors.DescriptorQueryManager;
import org.eclipse.persistence.descriptors.InheritancePolicy;
import org.eclipse.persistence.descriptors.changetracking.ChangeTracker;
import org.eclipse.persistence.exceptions.EclipseLinkException;
import org.eclipse.persistence.exceptions.IntegrityException;
import org.eclipse.persistence.exceptions.PersistenceUnitLoadingException;
import org.eclipse.persistence.exceptions.QueryException;
import org.eclipse.persistence.exceptions.ValidationException;
import org.eclipse.persistence.expressions.Expression;
import org.eclipse.persistence.expressions.ExpressionBuilder;
import org.eclipse.persistence.indirection.IndirectList;
import org.eclipse.persistence.internal.databaseaccess.Accessor;
import org.eclipse.persistence.internal.descriptors.PersistenceEntity;
import org.eclipse.persistence.internal.expressions.QueryKeyExpression;
import org.eclipse.persistence.internal.helper.Helper;
import org.eclipse.persistence.internal.indirection.BatchValueHolder;
import org.eclipse.persistence.internal.indirection.QueryBasedValueHolder;
import org.eclipse.persistence.internal.jpa.EJBQueryImpl;
import org.eclipse.persistence.internal.jpa.EntityManagerFactoryImpl;
import org.eclipse.persistence.internal.jpa.EntityManagerImpl;
import org.eclipse.persistence.internal.jpa.deployment.JPAInitializer;
import org.eclipse.persistence.internal.jpa.deployment.SEPersistenceUnitInfo;
import org.eclipse.persistence.internal.jpa.jdbc.DataSourceImpl;
import org.eclipse.persistence.internal.sessions.AbstractSession;
import org.eclipse.persistence.internal.sessions.RepeatableWriteUnitOfWork;
import org.eclipse.persistence.internal.sessions.UnitOfWorkImpl;
import org.eclipse.persistence.internal.weaving.PersistenceWeaved;
import org.eclipse.persistence.internal.weaving.PersistenceWeavedLazy;
import org.eclipse.persistence.jpa.JpaEntityManager;
import org.eclipse.persistence.jpa.JpaEntityManagerFactory;
import org.eclipse.persistence.jpa.JpaHelper;
import org.eclipse.persistence.jpa.JpaQuery;
import org.eclipse.persistence.jpa.PersistenceProvider;
import org.eclipse.persistence.logging.AbstractSessionLog;
import org.eclipse.persistence.logging.SessionLog;
import org.eclipse.persistence.mappings.DatabaseMapping;
import org.eclipse.persistence.platform.server.ServerPlatform;
import org.eclipse.persistence.platform.server.ServerPlatformBase;
import org.eclipse.persistence.platform.server.ServerPlatformUtils;
import org.eclipse.persistence.platform.server.was.WebSphere_7_Platform;
import org.eclipse.persistence.platform.server.wls.WebLogic_12_Platform;
import org.eclipse.persistence.queries.CursoredStreamPolicy;
import org.eclipse.persistence.queries.DataModifyQuery;
import org.eclipse.persistence.queries.DatabaseQuery;
import org.eclipse.persistence.queries.FetchGroup;
import org.eclipse.persistence.queries.FetchGroupTracker;
import org.eclipse.persistence.queries.InMemoryQueryIndirectionPolicy;
import org.eclipse.persistence.queries.ObjectLevelReadQuery;
import org.eclipse.persistence.queries.ReadAllQuery;
import org.eclipse.persistence.queries.ReadObjectQuery;
import org.eclipse.persistence.queries.ReportQuery;
import org.eclipse.persistence.queries.SQLCall;
import org.eclipse.persistence.queries.ScrollableCursorPolicy;
import org.eclipse.persistence.queries.ValueReadQuery;
import org.eclipse.persistence.sequencing.NativeSequence;
import org.eclipse.persistence.sequencing.Sequence;
import org.eclipse.persistence.sessions.Connector;
import org.eclipse.persistence.sessions.CopyGroup;
import org.eclipse.persistence.sessions.DatabaseLogin;
import org.eclipse.persistence.sessions.DatabaseSession;
import org.eclipse.persistence.sessions.DatasourceLogin;
import org.eclipse.persistence.sessions.DefaultConnector;
import org.eclipse.persistence.sessions.JNDIConnector;
import org.eclipse.persistence.sessions.Session;
import org.eclipse.persistence.sessions.SessionEvent;
import org.eclipse.persistence.sessions.SessionEventAdapter;
import org.eclipse.persistence.sessions.UnitOfWork;
import org.eclipse.persistence.sessions.changesets.ChangeRecord;
import org.eclipse.persistence.sessions.changesets.ObjectChangeSet;
import org.eclipse.persistence.sessions.changesets.UnitOfWorkChangeSet;
import org.eclipse.persistence.sessions.server.ClientSession;
import org.eclipse.persistence.sessions.server.ConnectionPolicy;
import org.eclipse.persistence.sessions.server.ConnectionPool;
import org.eclipse.persistence.sessions.server.ReadConnectionPool;
import org.eclipse.persistence.sessions.server.ServerSession;
import org.eclipse.persistence.testing.framework.ConnectionWrapper;
import org.eclipse.persistence.testing.framework.DriverWrapper;
import org.eclipse.persistence.testing.framework.QuerySQLTracker;
import org.eclipse.persistence.testing.framework.TestProblemException;
import org.eclipse.persistence.testing.framework.junit.JUnitTestCase;
import org.eclipse.persistence.testing.framework.junit.JUnitTestCaseHelper;
import org.eclipse.persistence.testing.models.jpa.advanced.Address;
import org.eclipse.persistence.testing.models.jpa.advanced.AdvancedTableCreator;
import org.eclipse.persistence.testing.models.jpa.advanced.Bungalow;
import org.eclipse.persistence.testing.models.jpa.advanced.Buyer;
import org.eclipse.persistence.testing.models.jpa.advanced.Canoe;
import org.eclipse.persistence.testing.models.jpa.advanced.ConcreteJob;
import org.eclipse.persistence.testing.models.jpa.advanced.Customer;
import org.eclipse.persistence.testing.models.jpa.advanced.Customizer;
import org.eclipse.persistence.testing.models.jpa.advanced.Dealer;
import org.eclipse.persistence.testing.models.jpa.advanced.Department;
import org.eclipse.persistence.testing.models.jpa.advanced.Door;
import org.eclipse.persistence.testing.models.jpa.advanced.Employee;
import org.eclipse.persistence.testing.models.jpa.advanced.EmployeeHolder;
import org.eclipse.persistence.testing.models.jpa.advanced.EmployeeListener;
import org.eclipse.persistence.testing.models.jpa.advanced.EmployeePopulator;
import org.eclipse.persistence.testing.models.jpa.advanced.EmploymentPeriod;
import org.eclipse.persistence.testing.models.jpa.advanced.Equipment;
import org.eclipse.persistence.testing.models.jpa.advanced.EquipmentCode;
import org.eclipse.persistence.testing.models.jpa.advanced.Event;
import org.eclipse.persistence.testing.models.jpa.advanced.FormerEmployment;
import org.eclipse.persistence.testing.models.jpa.advanced.GoldBuyer;
import org.eclipse.persistence.testing.models.jpa.advanced.Golfer;
import org.eclipse.persistence.testing.models.jpa.advanced.GolferPK;
import org.eclipse.persistence.testing.models.jpa.advanced.Hinge;
import org.eclipse.persistence.testing.models.jpa.advanced.HugeProject;
import org.eclipse.persistence.testing.models.jpa.advanced.Job;
import org.eclipse.persistence.testing.models.jpa.advanced.Lake;
import org.eclipse.persistence.testing.models.jpa.advanced.LargeProject;
import org.eclipse.persistence.testing.models.jpa.advanced.Man;
import org.eclipse.persistence.testing.models.jpa.advanced.NonEntity;
import org.eclipse.persistence.testing.models.jpa.advanced.PartnerLink;
import org.eclipse.persistence.testing.models.jpa.advanced.PhoneNumber;
import org.eclipse.persistence.testing.models.jpa.advanced.PlatinumBuyer;
import org.eclipse.persistence.testing.models.jpa.advanced.Project;
import org.eclipse.persistence.testing.models.jpa.advanced.ReadOnlyIsolated;
import org.eclipse.persistence.testing.models.jpa.advanced.Room;
import org.eclipse.persistence.testing.models.jpa.advanced.SmallProject;
import org.eclipse.persistence.testing.models.jpa.advanced.SpecialHugeProject;
import org.eclipse.persistence.testing.models.jpa.advanced.SuperLargeProject;
import org.eclipse.persistence.testing.models.jpa.advanced.Vegetable;
import org.eclipse.persistence.testing.models.jpa.advanced.VegetablePK;
import org.eclipse.persistence.testing.models.jpa.advanced.Woman;
import org.eclipse.persistence.testing.models.jpa.advanced.WorldRank;
import org.eclipse.persistence.testing.models.jpa.relationships.CustomerCollection;
import org.eclipse.persistence.testing.models.jpa.advanced.Material;
import org.eclipse.persistence.testing.models.jpa.advanced.MaterialHist;
import org.eclipse.persistence.testing.models.jpa.advanced.PlanArbeitsgang;
import org.eclipse.persistence.testing.models.jpa.advanced.MaterialEreignis;
import org.eclipse.persistence.testing.models.jpa.advanced.PlanArbeitsgangHist;
import org.eclipse.persistence.testing.tests.feature.TestDataSource;
import org.eclipse.persistence.testing.tests.jpa.unit.EMFProviderTest;
import org.eclipse.persistence.testing.tests.weaving.SimpleSessionLogWrapper;
import org.eclipse.persistence.tools.schemaframework.SequenceObjectDefinition;
import org.junit.Assert;

import junit.framework.AssertionFailedError;
import junit.framework.Test;
import junit.framework.TestSuite;

/**
 * Test the EntityManager API using the advanced model.
 */
public class EntityManagerJUnitTestSuite extends JUnitTestCase {

    /** The field length for the firstname */
    public static final int MAX_FIRST_NAME_FIELD_LENGTH = 255;

    public EntityManagerJUnitTestSuite() {
        super();
    }

    public EntityManagerJUnitTestSuite(String name) {
        super(name);
    }

    public static Test suite() {
        TestSuite suite = new TestSuite();
        suite.addTest(suiteSpring());
        suite.addTest(new EntityManagerJUnitTestSuite("testCacheUsage"));

        if (!isJPA10()) {
            suite.addTest(new EntityManagerJUnitTestSuite("testIsLoaded"));
        }
        return suite;
    }

    public static Test suiteSpring() {
        TestSuite suite = new TestSuite();
        suite.setName("EntityManagerJUnitTestSuite");
        //add unit tests
        suite.addTestSuite(EMFProviderTest.class);
        suite.addTest(new EntityManagerJUnitTestSuite("testSetup"));
        List<String> tests = new ArrayList<String>();
        tests.add("testEMFTargetServerEnforcing");
        tests.add("testSettingDetachedObject");
        tests.add("testMultipleExistenceChecksForDetachedObjects");
        tests.add("testMergeOfEntityWithDetachedReferences");
        tests.add("testClearEntityManagerWithoutPersistenceContext");
        tests.add("testDeadConnectionFailover");
        tests.add("testDeadPoolFailover");
        tests.add("testDeleteEmployee");
        tests.add("testDeleteEmployee_with_status_enum_collection_instantiated");
        tests.add("testDeleteMan");
        tests.add("testFindDeleteAllPersist");
        tests.add("testExtendedPersistenceContext");
        tests.add("testRemoveFlushFind");
        tests.add("testRemoveFlushPersistContains");
        tests.add("testTransactionRequired");
        tests.add("testSubString");
        tests.add("testFlushModeOnUpdateQuery");
        tests.add("testAnnotationDefaultLockModeNONEOnUpdateQuery");
        tests.add("testContainsRemoved");
        tests.add("testRefreshRemoved");
        tests.add("testRefreshNotManaged");
        tests.add("testDoubleMerge");
        tests.add("testDescriptorNamedQueryForMultipleQueries");
        tests.add("testDescriptorNamedQuery");
        tests.add("testClearEntityManagerWithoutPersistenceContextSimulateJTA");
        tests.add("testMultipleEntityManagerFactories");
        tests.add("testOneToManyDefaultJoinTableName");
        tests.add("testClosedEmShouldThrowException");
        tests.add("testRollbackOnlyOnException");
        tests.add("testUpdateAllProjectsWithNullTeamLeader");
        tests.add("testUpdateAllLargeProjectsWithNullTeamLeader");
        tests.add("testUpdateAllSmallProjectsWithNullTeamLeader");
        tests.add("testUpdateAllSpecialHugeProjectsWithNullTeamLeader");
        tests.add("testUpdateAllProjectsWithName");
        tests.add("testUpdateAllLargeProjectsWithName");
        tests.add("testUpdateAllSmallProjectsWithName");
        tests.add("testUpdateAllHugeProjectsWithName");
        tests.add("testUpdateAllSpecialHugeProjectsWithName");
        tests.add("testUpdateAllLargeProjects");
        tests.add("testUpdateAllSmallProjects");
        tests.add("testUpdateAllHugeProjects");
        tests.add("testUpdateAllSpecialHugeProjects");
        tests.add("testUpdateUsingTempStorageWithParameter");
        tests.add("testDeleteAllLargeProjectsWithNullTeamLeader");
        tests.add("testDeleteAllHugeProjectsWithNullTeamLeader");
        tests.add("testDeleteAllSpecialHugeProjectsWithNullTeamLeader");
        tests.add("testDeleteAllSmallProjectsWithNullTeamLeader");
        tests.add("testDeleteAllProjectsWithNullTeamLeader");
        tests.add("testDeleteAllPhonesWithNullOwner");
        tests.add("testSetFieldForPropertyAccessWithNewEM");
        tests.add("testSetFieldForPropertyAccessWithRefresh");
        tests.add("testSetFieldForPropertyAccess");
        tests.add("testInitializeFieldForPropertyAccess");
        tests.add("testCascadePersistToNonEntitySubclass");
        tests.add("testCascadeMergeManaged");
        tests.add("testCascadeMergeDetached");
        tests.add("testPrimaryKeyUpdatePKFK");
        tests.add("testPrimaryKeyUpdateSameValue");
        tests.add("testPrimaryKeyUpdate");
        tests.add("testRemoveNull");
        tests.add("testContainsNull");
        tests.add("testPersistNull");
        tests.add("testMergeNull");
        tests.add("testMergeRemovedObject");
        tests.add("testMergeDetachedObject");
        tests.add("testSerializedLazy");
        tests.add("testCloneable");
        tests.add("testLeftJoinOneToOneQuery");
        tests.add("testNullifyAddressIn");
        tests.add("testQueryOnClosedEM");
        tests.add("testIncorrectBatchQueryHint");
        tests.add("testFetchQueryHint");
        tests.add("testBatchQueryHint");
        tests.add("testQueryHints");
        tests.add("testParallelMultipleFactories");
        tests.add("testMultipleFactories");
        tests.add("testPersistenceProperties");
        tests.add("testBeginTransactionCloseCommitTransaction");
        tests.add("testBeginTransactionClose");
        tests.add("testClose");
        tests.add("testPersistOnNonEntity");
        tests.add("testWRITELock");
        tests.add("testOPTIMISTIC_FORCE_INCREMENTLock");
        tests.add("testReadOnlyTransactionalData");
        tests.add("testReadOnlyCachedLazyAssociation");
        tests.add("testReadOnlyCachedLazyAssociationInNestedEmbeddable");
        tests.add("testReadTransactionIsolation_OriginalInCache_UpdateAll_Refresh_Flush");
        tests.add("testReadTransactionIsolation_OriginalInCache_UpdateAll_Refresh");
        tests.add("testReadTransactionIsolation_OriginalInCache_UpdateAll_Flush");
        tests.add("testReadTransactionIsolation_OriginalInCache_UpdateAll");
        tests.add("testReadTransactionIsolation_OriginalInCache_CustomUpdate_Refresh_Flush");
        tests.add("testReadTransactionIsolation_OriginalInCache_CustomUpdate_Refresh");
        tests.add("testReadTransactionIsolation_OriginalInCache_CustomUpdate_Flush");
        tests.add("testReadTransactionIsolation_OriginalInCache_CustomUpdate");
        tests.add("testReadTransactionIsolation_UpdateAll_Refresh_Flush");
        tests.add("testReadTransactionIsolation_UpdateAll_Refresh");
        tests.add("testReadTransactionIsolation_UpdateAll_Flush");
        tests.add("testReadTransactionIsolation_UpdateAll");
        tests.add("testReadTransactionIsolation_CustomUpdate_Refresh_Flush");
        tests.add("testReadTransactionIsolation_CustomUpdate_Refresh");
        tests.add("testReadTransactionIsolation_CustomUpdate_Flush");
        tests.add("testReadTransactionIsolation_CustomUpdate");
        tests.add("testClearInTransaction");
        tests.add("testClearWithFlush");
        tests.add("testClear");
        tests.add("testEMFClose");
        tests.add("testCheckVersionOnMerge");
        tests.add("testFindWithNullPk");
        tests.add("testFindWithWrongTypePk");
        tests.add("testPersistManagedNoException");
        tests.add("testPersistManagedException");
        tests.add("testPersistRemoved");
        tests.add("testREADLock");
        tests.add("testOPTIMISTICLock");
        tests.add("testBatchWriteOPTIMISTICLock");
        tests.add("testPESSIMISTIC_READLock");
        tests.add("testPESSIMISTIC_WRITELock");
        tests.add("testPESSIMISTIC_READLockWithNoChanges");
        tests.add("testPESSIMISTIC_WRITELockWithNoChanges");
        tests.add("testPESSIMISTIC_READ_TIMEOUTLock");
        tests.add("testPESSIMISTIC_WRITE_TIMEOUTLock");
        tests.add("testPESSIMISTIC_ExtendedScope");
        tests.add("testRefreshOPTIMISTICLock");
        tests.add("testRefreshPESSIMISTIC_READLock");
        tests.add("testRefreshPESSIMISTIC_WRITELock");
        tests.add("testIgnoreRemovedObjectsOnDatabaseSync");
        tests.add("testIdentityOutsideTransaction");
        tests.add("testIdentityInsideTransaction");
        tests.add("testDatabaseSyncNewObject");
        tests.add("testSetRollbackOnly");
        tests.add("testFlushModeEmCommitQueryAuto");
        tests.add("testFlushModeEmCommit");
        tests.add("testFlushModeEmCommitQueryCommit");
        tests.add("testFlushModeEmAutoQueryAuto");
        tests.add("testFlushModeEmAuto");
        tests.add("testFlushModeEmAutoQueryCommit");
        tests.add("testSequencePreallocationUsingCallbackTest");
        tests.add("testForceSQLExceptionFor219097");
        tests.add("testRefreshInvalidateDeletedObject");
        tests.add("testClearWithFlush2");
        tests.add("testEMFWrapValidationException");
        tests.add("testEMDefaultTxType");
        tests.add("testMergeNewObject");
        tests.add("testMergeNewObject2");
        tests.add("testMergeNewObject3_UseSequencing");
        tests.add("testMergeNewObject3_DontUseSequencing");
        tests.add("testCreateEntityManagerFactory");
        tests.add("testCreateEntityManagerFactory2");
        tests.add("testPessimisticLockHintStartsTransaction");
        tests.add("testManyToOnePersistCascadeOnFlush");
        tests.add("testDiscoverNewReferencedObject");
        tests.add("testBulkDeleteThenMerge");
        tests.add("testNativeSequences");
        tests.add("testGetReference");
        tests.add("testGetReferenceUpdate");
        tests.add("testGetReferenceUsedInUpdate");
        tests.add("testBadGetReference");
        tests.add("testClassInstanceConverter");
        tests.add("test210280EntityManagerFromPUwithSpaceInNameButNotInPath");
        tests.add("test210280EntityManagerFromPUwithSpaceInPathButNotInName");
        tests.add("test210280EntityManagerFromPUwithSpaceInNameAndPath");
        tests.add("testNewObjectNotCascadePersist");
        tests.add("testConnectionPolicy");
        tests.add("testConverterIn");
        tests.add("testExceptionForPersistNonEntitySubclass");
        tests.add("testEnabledPersistNonEntitySubclass");
        tests.add("testCloneEmbeddable");
        tests.add("testCloseOnCommit");
        tests.add("testPersistOnCommit");
        tests.add("testFlushMode");
        tests.add("testEmbeddedNPE");
        tests.add("testCollectionAddNewObjectUpdate");
        tests.add("testEMCloseAndOpen");
        tests.add("testEMFactoryCloseAndOpen");
        tests.add("testPostAcquirePreReleaseEvents_InternalConnectionPool");
        tests.add("testPostAcquirePreReleaseEvents_ExternalConnectionPool");
        tests.add("testNoPersistOnCommit");
        tests.add("testNoPersistOnCommitProperties");
        tests.add("testForUOWInSharedCacheWithBatchQueryHint");
        tests.add("testNoPersistOnFlushProperties");
        tests.add("testUOWReferenceInExpressionCache");
        tests.add("testIsLoadedWithReference");
        tests.add("testIsLoadedWithoutReference");
        tests.add("testIsLoadedWithoutReferenceAttribute");
        tests.add("testGenerateSessionNameFromConnectionProperties");
        tests.add("testLockWithJoinedInheritanceStrategy");
        tests.add("testPreupdateEmbeddable");
        tests.add("testFindReadOnlyIsolated");
        tests.add("testInheritanceQuery");
        tests.add("testNullBasicMap");
        tests.add("testFlushClearFind");
        tests.add("testFlushClearFindNoCascadedLock");
        tests.add("testFlushClearQueryPk");
        tests.add("testFlushClearQueryNonPK");
        tests.add("testNestedBatchQueryHint");
        tests.add("testSequenceObjectDefinition");
        tests.add("testTemporalOnClosedEm");
        tests.add("testTransientMapping");
        tests.add("testUpdateAllProjects");
        tests.add("testUpdateUsingTempStorage");
        tests.add("testWeaving");
        tests.add("testRefreshForFlush");
        tests.add("testRefreshForCommit");
        tests.add("testRefreshLazyRelationship");
        tests.add("testNonRefreshLazyRelationship");
        tests.add("testChangeFlushChangeRefresh");
        tests.add("testChangeRecordKeepOldValue_Simple");
        tests.add("testChangeRecordKeepOldValue_TwoStep");
        tests.add("testSetNewAggregate");
        tests.add("testSetNewNestedAggregate");
        tests.add("testSetStartTime");
        tests.add("testObjectReferencedInBothEmAndSharedCache_AggregateObjectMapping");
        tests.add("testObjectReferencedInBothEmAndSharedCache_ObjectReferenceMappingVH");
        tests.add("testCharFieldDefaultNullValue");
        tests.add("testMergeNewReferencingOldChanged");
        tests.add("testApplicationManagedInServer");
        // Bug 340810 - merge problem: existing object referenced by new not cascade merged if not in cache.
        // Uncomment testMergeNewReferencingOldChangedClearCache when the bug is fixed.
        // tests.add("testMergeNewReferencingOldChangedClearCache");
        tests.add("testAddAndDeleteSameObject");
        tests.add("testDeleteAllProjects");
        tests.add("testEMFBuiltWithSession");
        tests.add("testLazyOneToOneFetchInitialization");
        tests.add("testProxyFetchDuringCommit");
        tests.add("testSequenceObjectWithSchemaName");
        tests.add("testSharedExpressionInQueries");
        tests.add("testNestedBatchQueryHints");
        tests.add("testReplaceElementCollection");
        tests.add("testProviderPropertySetting");
        tests.add("testBeginTransactionOnClosedEM");
        tests.add("testUpdateDetachedEntityWithRelationshipCascadeRefresh");
        tests.add("testForNPEInCloning"); //Bug#457480
        tests.add("testCopy"); //Bug#463350
        tests.add("testServerDetectionLogging"); //Bug#476018
//        if (isJPA21()){
//            tests.add("testUnsynchronizedPC");
//        }
        if (!isJPA10()) {
            tests.add("testDetachNull");
            tests.add("testDetachRemovedObject");
            tests.add("testLockingLeftJoinOneToOneQuery");
            tests.add("testLockingLeftJoinOneToOneQuery2");
            tests.add("testGetProperties");
            tests.add("testDetachNonEntity");
            tests.add("testFindWithProperties");
            tests.add("testDetachManagedObject");
            tests.add("testDetachNonManagedObject");
            tests.add("testPESSIMISTIC_FORCE_INCREMENTLock");
            tests.add("testGetLockModeType");
            tests.add("testGetEntityManagerFactory");
            tests.add("testConnectionPolicySetProperty");
            //Does not return underlying entitymanager tests.add("testUnWrapClass");
            tests.add("testIsLoaded");
            tests.add("testIsLoadedAttribute");
            tests.add("testGetIdentifier");
            tests.add("testGetHints");
            tests.add("testPESSIMISTIC_FORCE_INCREMENTLockOnNonVersionedEntity");
            tests.add("testSelectEmbeddable");
            tests.add("testNonPooledConnection");
            tests.add("testExclusiveIsolatedLeaksConnectionOnClear");
            tests.add("testSetTargetQueryOneToMany");
            tests.add("testNestedFetchQueryHints");
            tests.add("testInheritanceFetchJoinSecondCall");
        }
        tests.add("testDetachChildObjects");
        tests.add("testAutoCloseable");


        Collections.sort(tests);
        for (String test : tests) {
            suite.addTest(new EntityManagerJUnitTestSuite(test));
        }
        if (!isJPA10()) {
            suite.addTest(new EntityManagerJUnitTestSuite("testCascadeDetach"));
        }
        // Test must be last as clears database.
        suite.addTest(new EntityManagerJUnitTestSuite("testDeleteEverything"));
        return suite;
    }

    public void testSetup() {
        new AdvancedTableCreator().replaceTables(JUnitTestCase.getServerSession());
        clearCache();
        // Force uppercase for Postgres.
        if (getServerSession().getPlatform().isPostgreSQL()) {
            getServerSession().getLogin().setShouldForceFieldNamesToUpperCase(true);
        }
    }

    /**
     * Bug # 361552
     * This test verifies that EclipseLink does not ignore the Provider property passed to
     * createEntityManagerFactory();
     */
    public void testProviderPropertySetting(){
        if (!isOnServer()){
            Map properties = new HashMap();
            properties.put("jakarta.persistence.provider", "org.unknown.Provider");
            try{
                Persistence.createEntityManagerFactory(getPersistenceUnitName(), properties);
            }catch(PersistenceException ex){
                assertTrue("Wrong exception thrown when provider class set through properties.",ex.getMessage().contains("No Persistence provider for"));
                return;
            }
            fail("EclipseLink ignored persistence provider class provided through properties.");
        }
    }

    /**
     * Bug# 219097
     * This test would normally pass, but we purposely invoke an SQLException on the firstName field
     * so that we can test that an UnsupportedOperationException is not thrown as part of the
     * roll-back exception handling code for an SQLException.
     */
    public void testForceSQLExceptionFor219097() {
        boolean exceptionThrown = false;
        // Set an immutable properties Map on the em to test addition of properties to this map in the roll-back exception handler
        EntityManager em = createEntityManager(Collections.emptyMap());
        beginTransaction(em);

        Employee emp = new Employee();
        /*
         * Provoke an SQL exception by setting a field with a value greater than field length.
         * 1 - This test will not throw an exception without the Collections$emptyMap() set on the EntityhManager
         *       or the exceeded field length set on firstName.
         * 2 - This test will throw an UnsupportedOperationException if the map on AbstractSession is not cloned when immutable - bug fix
         * 3 - This test will throw an SQLException when operating normally due to the field length exception
         */
        StringBuffer firstName = new StringBuffer("firstName_maxfieldLength_");
        for(int i=0; i<MAX_FIRST_NAME_FIELD_LENGTH + 100; i++) {
            firstName.append("0");
        }
        emp.setFirstName(firstName.toString());
        em.persist(emp);

        try {
            commitTransaction(em);
        } catch (Exception e) {
            Throwable cause = e.getCause();
            if(cause instanceof UnsupportedOperationException) {
                exceptionThrown = true;
                fail(cause.getClass() + " Exception was thrown in error instead of expected SQLException.");
            } else {
                exceptionThrown = true;
            }
        } finally {
            closeEntityManager(em);
        }
        if(!exceptionThrown) {
            // Sybase does not through error when data too big, just truncates.
            if (!getDatabaseSession().getPlatform().isSybase()) {
                fail("An expected SQLException was not thrown.");
            }
        }
    }

    // JUnit framework will automatically execute all methods starting with test...
    public void testRefreshNotManaged() {
        EntityManager em = createEntityManager();
        beginTransaction(em);
        Employee emp = new Employee();
        emp.setFirstName("testRefreshNotManaged");
        try {
            em.refresh(emp);
            fail("entityManager.refresh(notManagedObject) didn't throw exception");
        } catch (IllegalArgumentException illegalArgumentException) {
            // expected behavior
        } catch (Exception exception ) {
            fail("entityManager.refresh(notManagedObject) threw a wrong exception: " + exception.getMessage());
        } finally {
            rollbackTransaction(em);
            closeEntityManager(em);
        }
    }

    public void testEMFClose() {
        // This test tests the bug fix for 260511
        // The NPE would be thrown if the EnityManager
        // was created through the constructor
        String errorMsg = "";
        EntityManagerFactory em = new EntityManagerFactoryImpl(JUnitTestCase.getServerSession());
        try {
            em.close();
        } catch (RuntimeException ex) {
            errorMsg ="EMFClose: " + ex.getMessage() +";";
        }

        if(errorMsg.length() > 0) {
            fail(errorMsg);
        }
    }

    public void testRefreshOPTIMISTICLock(){
        // Cannot create parallel entity managers in the server.
        if (! isOnServer()) {
            EntityManager em = createEntityManager();
            beginTransaction(em);
            Employee employee = null;

            try {
                employee = new Employee();
                employee.setFirstName("Billy");
                employee.setLastName("Madsen");
                em.persist(employee);
                commitTransaction(em);
            } catch (RuntimeException ex) {
                if (isTransactionActive(em)) {
                    rollbackTransaction(em);
                }

                closeEntityManager(em);
                throw ex;
            }

            EntityManager em2 = createEntityManager();
            Exception optimisticLockException = null;
            beginTransaction(em);

            try {
                em.refresh(employee, LockModeType.OPTIMISTIC);
                beginTransaction(em2);

                try {
                    Employee employee2 = em2.find(Employee.class, employee.getId());
                    employee2.setFirstName("Tilly");
                    commitTransaction(em2);
                } catch (RuntimeException ex) {
                    if (isTransactionActive(em2)) {
                        rollbackTransaction(em2);
                    }

                    throw ex;
                } finally {
                    closeEntityManager(em2);
                }

                try {
                    em.flush();
                } catch (PersistenceException exception) {
                    if (exception instanceof OptimisticLockException){
                        optimisticLockException = exception;
                    } else {
                        throw exception;
                    }
                }

                rollbackTransaction(em);
            } catch (RuntimeException ex) {
                if (isTransactionActive(em)){
                    rollbackTransaction(em);
                }

                closeEntityManager(em);
                throw ex;
            }

            try {
                beginTransaction(em);
                employee = em.find(Employee.class, employee.getId());
                em.remove(employee);
                commitTransaction(em);
            } catch (RuntimeException ex) {
                if (isTransactionActive(em)) {
                    rollbackTransaction(em);
                }

                closeEntityManager(em);
                throw ex;
            }

            assertFalse("Proper exception not thrown when EntityManager.lock(object, OPTIMISTIC) is used.", optimisticLockException == null);
        }
    }

    public void testRefreshPESSIMISTIC_READLock() {
        // Cannot create parallel entity managers in the server.
        if (! isOnServer() && isSelectForUpateNoWaitSupported()) {
            EntityManager em = createEntityManager();
            Department dept = null;

            try {
                beginTransaction(em);
                dept = new Department();
                dept.setName("Pessimistic Department");
                em.persist(dept);
                commitTransaction(em);
            } catch (RuntimeException ex) {
                if (isTransactionActive(em)) {
                    rollbackTransaction(em);
                }

                closeEntityManager(em);
                throw ex;
            }

            Exception pessimisticLockException = null;
            try {
                beginTransaction(em);
                dept = em.find(Department.class, dept.getId());
                em.lock(dept, LockModeType.PESSIMISTIC_READ);
                dept.setName("New Pessimistic Department");

                EntityManager em2 = createEntityManager();

                try {
                    beginTransaction(em2);
                    Department dept2 = em2.find(Department.class, dept.getId());
                    HashMap properties = new HashMap();
                    // According to the spec a 0 indicates a NOWAIT clause.
                    properties.put(QueryHints.PESSIMISTIC_LOCK_TIMEOUT, 0);
                    em2.refresh(dept2, LockModeType.PESSIMISTIC_READ, properties);
                } catch (PersistenceException ex) {
                    if (ex instanceof jakarta.persistence.PessimisticLockException) {
                        pessimisticLockException = ex;
                    } else {
                        throw ex;
                    }
                } finally {
                    closeEntityManagerAndTransaction(em2);
                }

                commitTransaction(em);
            } catch (RuntimeException ex) {
                if (isTransactionActive(em)) {
                    rollbackTransaction(em);
                }

                throw ex;
            } finally {
                closeEntityManager(em);
            }

            assertFalse("Proper exception not thrown when EntityManager.lock(object, PESSIMISTIC) is used.", pessimisticLockException == null);
        }
    }

    public void testRefreshPESSIMISTIC_WRITELock() {
        // Cannot create parallel entity managers in the server.
        if (! isOnServer() && isSelectForUpateNoWaitSupported()) {
            EntityManager em = createEntityManager();
            Department dept = null;

            try {
                beginTransaction(em);
                dept = new Department();
                dept.setName("Pessimistic Department");
                em.persist(dept);
                commitTransaction(em);
            } catch (RuntimeException ex) {
                if (isTransactionActive(em)) {
                    rollbackTransaction(em);
                }

                closeEntityManager(em);
                throw ex;
            }

            Exception pessimisticLockException = null;
            try {
                beginTransaction(em);
                dept = em.find(Department.class, dept.getId());
                em.lock(dept, LockModeType.PESSIMISTIC_WRITE);
                dept.setName("New Pessimistic Department");

                EntityManager em2 = createEntityManager();

                try {
                    beginTransaction(em2);
                    Department dept2 = em2.find(Department.class, dept.getId());
                    HashMap properties = new HashMap();
                    // According to the spec a 0 indicates a NOWAIT clause.
                    properties.put(QueryHints.PESSIMISTIC_LOCK_TIMEOUT, 0);
                    em2.refresh(dept2, LockModeType.PESSIMISTIC_WRITE, properties);
                } catch (PersistenceException ex) {
                    if (ex instanceof jakarta.persistence.PessimisticLockException) {
                        pessimisticLockException = ex;
                    } else {
                        throw ex;
                    }
                } finally {
                    closeEntityManagerAndTransaction(em2);
                }

                commitTransaction(em);
            } catch (RuntimeException ex) {
                if (isTransactionActive(em)) {
                    rollbackTransaction(em);
                }

                throw ex;
            } finally {
                closeEntityManager(em);
            }

            assertFalse("Proper exception not thrown when EntityManager.lock(object, PESSIMISTIC) is used.", pessimisticLockException == null);
        }
    }

    public void testRefreshRemoved() {
        // find an existing or create a new Employee
        String firstName = "testRefreshRemoved";
        Employee emp;
        EntityManager em = createEntityManager();
        List result = em.createQuery("SELECT OBJECT(e) FROM Employee e WHERE e.firstName = '"+firstName+"'").getResultList();
        if(!result.isEmpty()) {
            emp = (Employee)result.get(0);
        } else {
            emp = new Employee();
            emp.setFirstName(firstName);
            // persist the Employee
            try{
                beginTransaction(em);
                em.persist(emp);
                commitTransaction(em);
            }catch (RuntimeException ex){
                if (isTransactionActive(em)){
                    rollbackTransaction(em);
                }
                throw ex;
            }
        }

        try{
            beginTransaction(em);
            emp = em.find(Employee.class, emp.getId());

            if (!getServerSession().getPlatform().isSymfoware()){
                // Symfoware does not support delete all queries on multi-table entities
                // use a native query to delete instead
                em.createQuery("DELETE FROM Employee e WHERE e.firstName = '"+firstName+"'").executeUpdate();
            } else {
                // delete the Employee from the db
                em.createNativeQuery("DELETE FROM CMP3_EMPLOYEE WHERE F_NAME = '"+firstName+"'").executeUpdate();
            }
            // refresh the Employee - should fail with EntityNotFoundException
            em.refresh(emp);
            fail("entityManager.refresh(removedObject) didn't throw exception");
        } catch (EntityNotFoundException entityNotFoundException) {
            rollbackTransaction(em);
            // expected behavior
        } catch (Exception exception ) {
            rollbackTransaction(em);
            fail("entityManager.refresh(removedObject) threw a wrong exception: " + exception.getMessage());
        }
    }

    //Bug5955326, refresh should invalidate the shared cached object that was deleted outside of JPA.
    public void testRefreshInvalidateDeletedObject(){
        EntityManager em1 = createEntityManager();
        EntityManager em2 = createEntityManager();
        Address address = new Address();
        address.setCity("Kanata");
        // persist the Address
        try {

            //Ensure shared cache being used.
            boolean isIsolated = ((EntityManagerImpl)em1).getServerSession().getClassDescriptorForAlias("Address").isIsolated();
            if(isIsolated){
                throw new Exception("This test should use non-isolated cache setting class descriptor for test.");
            }

            beginTransaction(em1);
            em1.persist(address);
            commitTransaction(em1);

            //Cache the Address
            em1 = createEntityManager();
            beginTransaction(em1);
            address = em1.find(Address.class, address.getID());

            // Delete Address outside of JPA so that the object still stored in the cache.
            em2 = createEntityManager();
            beginTransaction(em2);
            em2.createNativeQuery("DELETE FROM CMP3_ADDRESS where ADDRESS_ID = ?1").setParameter(1, address.getID()).executeUpdate();
            commitTransaction(em2);

            //Call refresh to invalidate the object
            em1.refresh(address);
        }catch (Exception e){
            //expected exception
        } finally{
            if (isTransactionActive(em1)) {
                rollbackTransaction(em1);
            }
        }

        //Verify
        beginTransaction(em1);
        address=em1.find(Address.class, address.getID());
        commitTransaction(em1);

        assertNull("The deleted object is still valid in share cache", address);

    }

    public void testCacheUsage() {
        EntityManager em = createEntityManager();
        Employee emp = new Employee();
        emp.setFirstName("Mark");
        // persist the Employee
        try {
            beginTransaction(em);
            em.persist(emp);
            commitTransaction(em);
        } catch (RuntimeException ex) {
            if (isTransactionActive(em)) {
                rollbackTransaction(em);
            }
            throw ex;
        }
        clearCache();
        // Create new entity manager to avoid extended uow of work cache hits.
        em = createEntityManager();
        beginTransaction(em);
        List result = em.createQuery("SELECT OBJECT(e) FROM Employee e").getResultList();
        commitTransaction(em);
        Object obj = getServerSession().getIdentityMapAccessor().getFromIdentityMap(result.get(0));
        assertTrue("Failed to load the object into the shared cache when there were no changes in the UOW", obj != null);
        try{
            beginTransaction(em);
            emp = em.find(Employee.class, emp.getId());
            em.remove(emp);
            commitTransaction(em);
        } catch (RuntimeException exception) {
            if (isTransactionActive(em)) {
                rollbackTransaction(em);
            }
            throw exception;
        }
    }

    public void testContainsRemoved() {
        // find an existing or create a new Employee
        String firstName = "testContainsRemoved";
        Employee emp;
        EntityManager em = createEntityManager();
        List result = em.createQuery("SELECT OBJECT(e) FROM Employee e WHERE e.firstName = '"+firstName+"'").getResultList();
        if(!result.isEmpty()) {
            emp = (Employee)result.get(0);
        } else {
            emp = new Employee();
            emp.setFirstName(firstName);
            // persist the Employee
            try{
                beginTransaction(em);
                em.persist(emp);
                commitTransaction(em);
            }catch (RuntimeException ex){
                if (isTransactionActive(em)){
                    rollbackTransaction(em);
                }
                throw ex;
            }
        }

        boolean containsRemoved = true;
        try{
            beginTransaction(em);
            emp = em.find(Employee.class, emp.getId());
            em.remove(emp);
            containsRemoved = em.contains(emp);
            commitTransaction(em);
        }catch (RuntimeException t){
            if (isTransactionActive(em)){
                rollbackTransaction(em);
            }
            throw t;
        }

        assertFalse("entityManager.contains(removedObject)==true ", containsRemoved);
    }

    public void testFlushModeEmAutoQueryCommit() {
        internalTestFlushMode(FlushModeType.AUTO, FlushModeType.COMMIT);
    }

    public void testFlushModeEmAuto() {
        internalTestFlushMode(FlushModeType.AUTO, null);
    }

    public void testFlushModeEmAutoQueryAuto() {
        internalTestFlushMode(FlushModeType.AUTO, FlushModeType.AUTO);
    }

    public void testFlushModeEmCommitQueryCommit() {
        internalTestFlushMode(FlushModeType.COMMIT, FlushModeType.COMMIT);
    }

    public void testFlushModeEmCommit() {
        internalTestFlushMode(FlushModeType.COMMIT, null);
    }

    public void testFlushModeEmCommitQueryAuto() {
        internalTestFlushMode(FlushModeType.COMMIT, FlushModeType.AUTO);
    }

    public void internalTestFlushMode(FlushModeType emFlushMode, FlushModeType queryFlushMode) {
        // create a new Employee
        String firstName = "testFlushMode";

        // make sure no Employee with the specified firstName exists.
        EntityManager em = createEntityManager();
        try{
            beginTransaction(em);
            Query q = em.createQuery("SELECT e FROM Employee e WHERE e.firstName = '"+firstName+"'");
            for (Object oldData : q.getResultList()) {
                em.remove(oldData);
            }
            commitTransaction(em);
        }catch (RuntimeException ex){
            if (isTransactionActive(em)){
                rollbackTransaction(em);
            }
            throw ex;
        }
        clearCache();

        Employee emp;
        FlushModeType emFlushModeOriginal = em.getFlushMode();
        // create a new Employee
        emp = new Employee();
        emp.setFirstName(firstName);
        boolean flushed = true;
        Employee result = null;
        try{
            beginTransaction(em);
            Query query = em.createQuery("SELECT OBJECT(e) FROM Employee e WHERE e.firstName like '"+firstName+"'");
            if(queryFlushMode != null) {
                query.setFlushMode(queryFlushMode);
            }
            emFlushModeOriginal = em.getFlushMode();
            em.setFlushMode(emFlushMode);
            em.persist(emp);
            result = (Employee) query.getSingleResult();
            result.toString();
        } catch (jakarta.persistence.NoResultException ex) {
            // failed to flush to database
            flushed = false;
        } finally {
            rollbackTransaction(em);
            em.setFlushMode(emFlushModeOriginal);
        }

        boolean shouldHaveFlushed;
        if(queryFlushMode != null) {
            shouldHaveFlushed = queryFlushMode == FlushModeType.AUTO;
        } else {
            shouldHaveFlushed = emFlushMode == FlushModeType.AUTO;
        }
        if(shouldHaveFlushed != flushed) {
            if(flushed) {
                fail("Flushed to database");
            } else {
                fail("Failed to flush to database");
            }
        }

    }

    public void testFlushModeOnUpdateQuery() {
        // find an existing or create a new Employee
        String firstName = "testFlushModeOnUpdateQuery";
        Employee emp;
        EntityManager em = createEntityManager();
        emp = new Employee();
        emp.setFirstName(firstName);
        try{
            try{
                beginTransaction(em);
                Query readQuery = em.createQuery("SELECT OBJECT(e) FROM Employee e WHERE e.phoneNumbers IS EMPTY and e.firstName like '"+firstName+"'");
                Query updateQuery = null;

                if (getServerSession().getPlatform().isSymfoware()){
                    updateQuery = em.createNativeQuery("UPDATE CMP3_EMPLOYEE SET VERSION = (VERSION + 1) WHERE F_NAME LIKE '" + firstName + "' AND EMP_ID in (SELECT EMP_ID FROM CMP3_SALARY)");
                } else {
                    updateQuery = em.createQuery("UPDATE Employee e set e.salary = 100 where e.firstName like '" + firstName + "'");
                }
                updateQuery.setFlushMode(FlushModeType.AUTO);
                em.persist(emp);
                updateQuery.executeUpdate();
                if (getServerSession().getPlatform().isSymfoware()){
                    updateQuery = em.createNativeQuery("UPDATE CMP3_SALARY SET SALARY = 100 WHERE EMP_ID IN (SELECT EMP_ID FROM CMP3_EMPLOYEE WHERE F_NAME LIKE '" + firstName + "')");
                    updateQuery.setFlushMode(FlushModeType.AUTO);
                    updateQuery.executeUpdate();
                }
                Employee result = (Employee) readQuery.getSingleResult();
                result.toString();
            }catch (jakarta.persistence.EntityNotFoundException ex){
                rollbackTransaction(em);
                fail("Failed to flush to database");
            }
            em.refresh(emp);
            em.remove(emp);
            commitTransaction(em);
        }catch(RuntimeException ex){
            if (isTransactionActive(em)){
                rollbackTransaction(em);
            }
            if (usesSOP() && !isSOPRecoverable()) {
                // TODO: refresh should throw PersistenceException?
                if (ex instanceof QueryException && ((QueryException)ex).getErrorCode() == QueryException.SOP_OBJECT_IS_NOT_FOUND) {
                    // refresh is expected to fail because SOP field is set to null after bulk update
                    return;
                } else {
                    fail("Wrong exception: " + ex);
                }
            } else {
                throw ex;
            }
        }
        assertTrue("Failed to flush to Database", emp.getSalary() == 100);
    }

    public void testAnnotationDefaultLockModeNONEOnUpdateQuery() {
        if ((JUnitTestCase.getServerSession()).getPlatform().isSymfoware()) {
            getServerSession().logMessage("Test testAnnotationDefaultLockModeNONEOnUpdateQuery skipped for this platform, "
                    + "Symfoware doesn't support UpdateAll/DeleteAll on multi-table objects (see rfe 298193).");
            return;
        }
        EntityManager em = createEntityManager();

        try {
            beginTransaction(em);
            em.createNamedQuery("UpdateEmployeeQueryWithLockModeNONE").executeUpdate();
            commitTransaction(em);
        } catch (Exception e) {
            if (isTransactionActive(em)){
                rollbackTransaction(em);
            }

            fail("Update query failed: " + e.getMessage());
        } finally {
            closeEntityManager(em);
        }
    }

    public void testSetRollbackOnly(){
        EntityManager em = createEntityManager();
        beginTransaction(em);
        Employee emp = null;
        Employee emp2 = null;
        try{
            emp = new Employee();
            emp.setFirstName("Bob");
            emp.setLastName("Fisher");
            em.persist(emp);
            emp2 = new Employee();
            emp2.setFirstName("Anthony");
            emp2.setLastName("Walace");
            em.persist(emp2);
            commitTransaction(em);
        }catch (RuntimeException ex){
            if (isTransactionActive(em)){
                rollbackTransaction(em);
            }
            closeEntityManager(em);
            throw ex;
        }
        clearCache();
        em = createEntityManager();
        beginTransaction(em);
        List result = em.createQuery("SELECT e FROM Employee e where e.id = " + emp.getId() + " or e.id = " + emp2.getId()).getResultList();
        emp = (Employee)result.get(0);
        emp.toString();
        emp2 = (Employee)result.get(1);
        String newName = ""+System.currentTimeMillis();
        emp2.setFirstName(newName);
        em.flush();
        emp2.setLastName("Whatever");
        emp2.setVersion(0);
        try{
            em.flush();
        }catch (Exception ex){
            /*
            If JTA case after exception has occurred the connection is immediately closed.
            Attempt to perform read causes a new connection to be acquired.
            Because the unitOfWork is no longer in transaction the connection is acquired by ServerSession.
            In case the ServerSession's read connection pool is JTA-managed the acquired connection that attempt fails on some app. servers (WLS)
            while others (GlassFish) return connection that correspond to no transaction at all
            (that would cause the old data to be read and the test to fail).
            Alternatively, if  a non-JTA-managed connection pool used for reading then the newly acquired connection is always returns the old object
            (and the test would fail, again).
            Note that in case of internal connection pool the connection is still kept after the exception is thrown
            and therefore the read returns the new data (the test passes).
             */
            if (!isOnServer()) {
                em.clear(); // prevent the flush again
                try {
                    String eName = (String) em.createQuery("SELECT e.firstName FROM Employee e where e.id = " + emp2.getId()).getSingleResult();
                    assertTrue("Failed to keep txn open for set RollbackOnly", eName.equals(newName));
                } catch (Exception ignore) {
                }
            }
        }
        try {
            if (isOnServer()) {
                assertTrue("Failed to mark txn rollback only", !isTransactionActive(em));
            } else {
                assertTrue("Failed to mark txn rollback only", em.getTransaction().getRollbackOnly());
            }
        } finally{
            try{
                commitTransaction(em);
            }catch (RollbackException ex){
                return;
            }catch (RuntimeException ex){
                if (ex.getCause() instanceof jakarta.transaction.RollbackException) {
                    return;
                }
                if (ex.getCause() instanceof jakarta.persistence.RollbackException) {
                    return;
                }
                if (isTransactionActive(em)){
                    rollbackTransaction(em);
                }
                throw ex;
            }
        }
        fail("Failed to throw rollback exception");
    }

    public void testSubString() {
        if ((JUnitTestCase.getServerSession()).getPlatform().isSymfoware()) {
            getServerSession().logMessage("Test testSubString skipped for this platform, "
                    + "Symfoware doesn't allow dynamic parameter as first argument of SUBSTRING. (bug 304897)");
            return;
        }

        // find an existing or create a new Employee
        String firstName = "testSubString";
        Employee emp;
        EntityManager em = createEntityManager();
        List result = em.createQuery("SELECT OBJECT(e) FROM Employee e WHERE e.firstName = '"+firstName+"'").getResultList();
        if(!result.isEmpty()) {
            emp = (Employee)result.get(0);
        } else {
            emp = new Employee();
            emp.setFirstName(firstName);
            // persist the Employee
            try{
                beginTransaction(em);
                em.persist(emp);
                commitTransaction(em);
            }catch (RuntimeException ex){
                if (isTransactionActive(em)){
                    rollbackTransaction(em);
                }
                throw ex;
            }
        }

        int firstIndex = 1;
        int lastIndex = firstName.length();
        List employees = em.createQuery("SELECT object(e) FROM Employee e where e.firstName = substring(:p1, :p2, :p3)").
            setParameter("p1", firstName).
            setParameter("p2", firstIndex).
            setParameter("p3", lastIndex).
            getResultList();

        // clean up
        try{
            beginTransaction(em);
            em.createQuery("DELETE FROM Employee e WHERE e.firstName = '"+firstName+"'").executeUpdate();
            commitTransaction(em);
        }catch (RuntimeException ex){
            if (isTransactionActive(em)){
                rollbackTransaction(em);
            }
            throw ex;
        }

        assertFalse("employees.isEmpty()==true ", employees.isEmpty());
    }

    public void testNewObjectNotCascadePersist(){
        IllegalStateException exception = null;
        EntityManager em = createEntityManager();
        beginTransaction(em);
        Golfer g = new Golfer();
        WorldRank wr = new WorldRank();
        g.setWorldRank(wr);
        em.persist(g);
        try{
            em.flush();
        }catch (IllegalStateException ex){
            exception = ex;
        }finally{
            rollbackTransaction(em);
            closeEntityManager(em);
        }
        assertNotNull("Failed to throw IllegalStateException see bug: 237279 ", exception);

    }

    public void testDatabaseSyncNewObject() {
        EntityManager em = createEntityManager();

        beginTransaction(em);

        try{
            Project project = new LargeProject();
            em.persist(project);
            project.setName("Blah");
            project.setTeamLeader(new Employee());
            project.getTeamLeader().addProject(project);
            em.flush();
        }catch (RuntimeException ex){
            rollbackTransaction(em);
            if (ex instanceof IllegalStateException)
            return;
        }

        fail("Failed to throw illegal argument when finding unregistered new object cascading on database sync");

    }

    public void testTransactionRequired() {
        String firstName = "testTransactionRequired";
        Employee emp = new Employee();
        emp.setFirstName(firstName);

        String noException = "";
        String wrongException = "";

        try {
            createEntityManager().flush();
            noException = noException + " flush;";
        } catch (TransactionRequiredException transactionRequiredException) {
            // expected behavior
        } catch (RuntimeException ex) {
            wrongException = wrongException + " flush: " + ex.getMessage() +";";
        }

        String errorMsg = "";
        if(noException.length() > 0) {
            errorMsg = "No exception thrown: " + noException;
        }
        if(wrongException.length() > 0) {
            if(errorMsg.length() > 0) {
                errorMsg = errorMsg + " ";
            }
            errorMsg = errorMsg + "Wrong exception thrown: " + wrongException;
        }
        if(errorMsg.length() > 0) {
            fail(errorMsg);
        }
    }

    public void testIdentityInsideTransaction() {
        EntityManager em = createEntityManager();
        beginTransaction(em);

        Query query = em.createQuery("SELECT e FROM PhoneNumber e");
        List<PhoneNumber> phoneNumbers = query.getResultList();
        for (PhoneNumber phoneNumber : phoneNumbers) {
            Employee emp = phoneNumber.getOwner();
            Collection<PhoneNumber> numbers = emp.getPhoneNumbers();
            assertTrue(numbers.contains(phoneNumber));
        }

        commitTransaction(em);
        closeEntityManager(em);
    }

    public void testIdentityOutsideTransaction() {
        EntityManager em = getEntityManagerFactory().createEntityManager();

        Query query = em.createQuery("SELECT e FROM PhoneNumber e");
        List<PhoneNumber> phoneNumbers = query.getResultList();
        for (PhoneNumber phoneNumber : phoneNumbers) {
            Employee emp = phoneNumber.getOwner();
            Collection<PhoneNumber> numbers = emp.getPhoneNumbers();
            assertTrue(numbers.contains(phoneNumber));
        }

        closeEntityManager(em);
    }

    public void testIgnoreRemovedObjectsOnDatabaseSync() {
        EntityManager em = createEntityManager();

        beginTransaction(em);
        Query phoneQuery = em.createQuery("Select p from PhoneNumber p where p.owner.lastName like 'Dow%'");
        Query empQuery = em.createQuery("Select e FROM Employee e where e.lastName like 'Dow%'");
        //--setup
        try{
            Employee emp = new Employee();
            emp.setLastName("Dowder");
            PhoneNumber phone = new PhoneNumber("work", "613", "5555555");
            emp.addPhoneNumber(phone);
            phone = new PhoneNumber("home", "613", "4444444");
            emp.addPhoneNumber(phone);
            Address address = new Address("SomeStreet", "somecity", "province", "country", "postalcode");
            emp.setAddress(address);
            em.persist(emp);
            em.flush();

            emp = new Employee();
            emp.setLastName("Dows");
            phone = new PhoneNumber("work", "613", "2222222");
            emp.addPhoneNumber(phone);
            phone = new PhoneNumber("home", "613", "1111111");
            emp.addPhoneNumber(phone);
            address = new Address("street1", "city1", "province1", "country1", "postalcode1");
            emp.setAddress(address);
            em.persist(emp);
            em.flush();
            //--end setup

            List<Employee> emps = empQuery.getResultList();

            List phones = phoneQuery.getResultList();
            for (Iterator iterator = phones.iterator(); iterator.hasNext();){
                em.remove(iterator.next());
            }
            em.flush();

            for (Iterator<Employee> iterator = emps.iterator(); iterator.hasNext();){
                em.remove(iterator.next());
            }
        }catch (RuntimeException ex){
            rollbackTransaction(em);
            throw ex;
        }
        try{
            em.flush();
        }catch (IllegalStateException ex){
            rollbackTransaction(em);
            closeEntityManager(em);
            em = createEntityManager();
            beginTransaction(em);
            try{
                phoneQuery = em.createQuery("Select p from PhoneNumber p where p.owner.lastName like 'Dow%'");
                empQuery = em.createQuery("Select e from Employee e where e.lastName like 'Dow%'");
                List<Employee> emps =  empQuery.getResultList();
                List phones = phoneQuery.getResultList();
                for (Iterator iterator = phones.iterator(); iterator.hasNext();){
                    em.remove(iterator.next());
                }
                for (Iterator<Employee> iterator = emps.iterator(); iterator.hasNext();){
                    em.remove(iterator.next());
                }
                commitTransaction(em);
            }catch (RuntimeException re){
                if (isTransactionActive(em)){
                    rollbackTransaction(em);
                }
                throw re;
            }
            fail("Failed to ignore the removedobject when cascading on database sync");
        }

        commitTransaction(em);
    }

    public void testREADLock(){
        // Cannot create parallel entity managers in the server.
        if (isOnServer()) {
            return;
        }

        EntityManager em = createEntityManager();
        beginTransaction(em);
        Employee employee = null;

        try {
            employee = new Employee();
            employee.setFirstName("Mark");
            employee.setLastName("Madsen");
            em.persist(employee);
            commitTransaction(em);
        }catch (RuntimeException ex){
            if (isTransactionActive(em)){
                rollbackTransaction(em);
            }
            closeEntityManager(em);
            throw ex;
        }
        EntityManager em2 = createEntityManager();
        Exception optimisticLockException = null;

        beginTransaction(em);
        try{
            employee = em.find(Employee.class, employee.getId());
            em.lock(employee, LockModeType.READ);
            em2.getTransaction().begin();
            try{
                Employee employee2 = em2.find(Employee.class, employee.getId());
                employee2.setFirstName("Michael");
                em2.getTransaction().commit();
                em2.close();
            }catch (RuntimeException ex){
                em2.getTransaction().rollback();
                em2.close();
                throw ex;
            }

            try{
                em.flush();
            } catch (PersistenceException exception) {
                if (exception instanceof OptimisticLockException){
                    optimisticLockException = exception;
                }else{
                    throw exception;
                }
            }
            rollbackTransaction(em);
        }catch (RuntimeException ex){
            if (isTransactionActive(em)){
                rollbackTransaction(em);
            }
            closeEntityManager(em);
            throw ex;
        }
        beginTransaction(em);
        try{
            employee = em.find(Employee.class, employee.getId());
            em.remove(employee);
            commitTransaction(em);
        }catch (RuntimeException ex){
            if (isTransactionActive(em)){
                rollbackTransaction(em);
            }
            closeEntityManager(em);
            throw ex;
        }

        if (optimisticLockException == null){
            fail("Proper exception not thrown when EntityManager.lock(object, READ) is used.");
        }
    }

    public void testOPTIMISTIC_FORCE_INCREMENTLock(){
        // Cannot create parallel transactions.
        if (! isOnServer()) {
            EntityManager em = createEntityManager();
            Employee employee;

            try {
                beginTransaction(em);
                employee = new Employee();
                employee.setFirstName("Philip");
                employee.setLastName("Madsen");
                em.persist(employee);
                commitTransaction(em);
            } catch (RuntimeException ex) {
                if (isTransactionActive(em)) {
                    rollbackTransaction(em);
                }

                closeEntityManager(em);
                throw ex;
            }

            Exception optimisticLockException = null;

            try {
                beginTransaction(em);
                employee = em.find(Employee.class, employee.getId(), LockModeType.OPTIMISTIC_FORCE_INCREMENT);
                EntityManager em2 = createEntityManager();

                try {
                    beginTransaction(em2);
                    Employee employee2 = em2.find(Employee.class, employee.getId());
                    employee2.setFirstName("Tulip");
                    commitTransaction(em2);
                } catch (RuntimeException ex) {
                    if (isTransactionActive(em2)) {
                        rollbackTransaction(em2);
                    }

                    throw ex;
                } finally {
                    closeEntityManager(em2);
                }

                commitTransaction(em);
            } catch (RollbackException exception) {
                if (exception.getCause() instanceof OptimisticLockException){
                    optimisticLockException = exception;
                }
            } catch (RuntimeException ex) {
                if (isTransactionActive(em)) {
                    rollbackTransaction(em);
                }

                closeEntityManager(em);
                throw ex;
            }

            beginTransaction(em);

            try {
                employee = em.find(Employee.class, employee.getId());
                em.remove(employee);
                commitTransaction(em);
            } catch (RuntimeException ex) {
                if (isTransactionActive(em)) {
                    rollbackTransaction(em);
                }

                throw ex;
            } finally {
                closeEntityManager(em);
            }

            assertFalse("Proper exception not thrown when EntityManager.lock(object, WRITE) is used.", optimisticLockException == null);
        }
    }

    // Ensure optimistic locking works with batch writing.
    public void testBatchWriteOPTIMISTICLock() {
        boolean old = getDatabaseSession().getPlatform().usesBatchWriting();
        getDatabaseSession().getPlatform().setUsesBatchWriting(true);
        try {
            testOPTIMISTICLock();
        } finally {
            getDatabaseSession().getPlatform().setUsesBatchWriting(old);
        }
    }

    public void testOPTIMISTICLock() {
        // Cannot create parallel entity managers in the server.
        if (! isOnServer()) {
            EntityManager em = createEntityManager();
            beginTransaction(em);
            Employee employee = null;

            try {
                employee = new Employee();
                employee.setFirstName("Harry");
                employee.setLastName("Madsen");
                em.persist(employee);
                commitTransaction(em);
            } catch (RuntimeException ex) {
                if (isTransactionActive(em)) {
                    rollbackTransaction(em);
                }

                closeEntityManager(em);
                throw ex;
            }

            EntityManager em2 = createEntityManager();
            Exception optimisticLockException = null;
            beginTransaction(em);

            try {
                employee = em.find(Employee.class, employee.getId());
                em.lock(employee, LockModeType.OPTIMISTIC);
                beginTransaction(em2);

                try {
                    Employee employee2 = em2.find(Employee.class, employee.getId());
                    employee2.setFirstName("Michael");
                    commitTransaction(em2);
                } catch (RuntimeException ex) {
                    if (isTransactionActive(em2)) {
                        rollbackTransaction(em2);
                    }

                    throw ex;
                } finally {
                    closeEntityManager(em2);
                }

                try {
                    em.flush();
                } catch (PersistenceException exception) {
                    if (exception instanceof OptimisticLockException){
                        optimisticLockException = exception;
                    } else {
                        throw exception;
                    }
                }

                rollbackTransaction(em);
            } catch (RuntimeException ex) {
                if (isTransactionActive(em)){
                    rollbackTransaction(em);
                }

                closeEntityManager(em);
                throw ex;
            }

            try {
                beginTransaction(em);
                employee = em.find(Employee.class, employee.getId());
                em.remove(employee);
                commitTransaction(em);
            } catch (RuntimeException ex) {
                if (isTransactionActive(em)) {
                    rollbackTransaction(em);
                }

                closeEntityManager(em);
                throw ex;
            }

            assertFalse("Proper exception not thrown when EntityManager.lock(object, OPTIMISTIC) is used.", optimisticLockException == null);
        }
    }

    // This test issues a LOCK and a LOCK NOWAIT.
    public void testPESSIMISTIC_READLock() {
        // Cannot create parallel entity managers in the server.
        if (! isOnServer() && isSelectForUpateNoWaitSupported()) {
            EntityManager em = createEntityManager();
            Department dept = null;

            try {
                beginTransaction(em);
                dept = new Department();
                dept.setName("Pessimistic Department");
                em.persist(dept);
                commitTransaction(em);
            } catch (RuntimeException ex) {
                if (isTransactionActive(em)) {
                    rollbackTransaction(em);
                }

                closeEntityManager(em);
                throw ex;
            }

            Exception pessimisticLockException = null;

            try {
                beginTransaction(em);
                dept = em.find(Department.class, dept.getId());
                em.lock(dept, LockModeType.PESSIMISTIC_READ);
                dept.setName("New Pessimistic Department");

                EntityManager em2 = createEntityManager();

                try {
                    beginTransaction(em2);
                    Department dept2 = em2.find(Department.class, dept.getId());
                    HashMap properties = new HashMap();
                    // According to the spec a 0 indicates a NOWAIT clause.
                    properties.put(QueryHints.PESSIMISTIC_LOCK_TIMEOUT, 0);
                    em2.lock(dept2, LockModeType.PESSIMISTIC_READ, properties);
                } catch (PersistenceException ex) {
                    if (ex instanceof jakarta.persistence.PessimisticLockException) {
                        pessimisticLockException = ex;
                    } else {
                        throw ex;
                    }
                } finally {
                    rollbackTransaction(em2);
                    closeEntityManager(em2);
                }

                commitTransaction(em);
            } catch (RuntimeException ex) {
                if (isTransactionActive(em)) {
                    rollbackTransaction(em);
                }

                throw ex;
            } finally {
                closeEntityManager(em);
            }

            assertFalse("Proper exception not thrown when EntityManager.lock(object, PESSIMISTIC) is used.", pessimisticLockException == null);
        }
    }

    public void testPESSIMISTIC_WRITELock() {
        // Cannot create parallel entity managers in the server.
        if (! isOnServer() && isSelectForUpateNoWaitSupported()) {
            EntityManager em = createEntityManager();
            Department dept = null;

            try {
                beginTransaction(em);
                dept = new Department();
                dept.setName("Pessimistic Department");
                em.persist(dept);
                commitTransaction(em);
            } catch (RuntimeException ex) {
                if (isTransactionActive(em)) {
                    rollbackTransaction(em);
                }

                closeEntityManager(em);
                throw ex;
            }

            Exception pessimisticLockException = null;

            try {
                beginTransaction(em);
                dept = em.find(Department.class, dept.getId());
                em.lock(dept, LockModeType.PESSIMISTIC_WRITE);
                dept.setName("New Pessimistic Department");

                EntityManager em2 = createEntityManager();

                try {
                    beginTransaction(em2);
                    Department dept2 = em2.find(Department.class, dept.getId());
                    HashMap properties = new HashMap();
                    // According to the spec a 0 indicates a NOWAIT clause.
                    properties.put(QueryHints.PESSIMISTIC_LOCK_TIMEOUT, 0);
                    em2.lock(dept2, LockModeType.PESSIMISTIC_WRITE, properties);
                } catch (PersistenceException ex) {
                    if (ex instanceof jakarta.persistence.PessimisticLockException) {
                        pessimisticLockException = ex;
                    } else {
                        throw ex;
                    }
                } finally {
                    rollbackTransaction(em2);
                    closeEntityManager(em2);
                }

                commitTransaction(em);
            } catch (RuntimeException ex) {
                if (isTransactionActive(em)) {
                    rollbackTransaction(em);
                }

                throw ex;
            } finally {
                closeEntityManager(em);
            }

            assertFalse("Proper exception not thrown when EntityManager.lock(object, PESSIMISTIC) is used.", pessimisticLockException == null);
        }
    }

    public void testPESSIMISTIC_FORCE_INCREMENTLock() {
        if (!isSelectForUpateSupported()) {
            return;
        }
        if ((JUnitTestCase.getServerSession()).getPlatform().isHANA()) {
            // HANA currently doesn't support pessimistic locking with queries on multiple tables
            // feature is under development (see bug 384129), but test should be skipped for the time being
            return;
        }
        Employee employee = null;
        Integer version1;

        EntityManager em = createEntityManager();

        try {
            beginTransaction(em);
            employee = new Employee();
            employee.setFirstName("Guillaume");
            employee.setLastName("Aujet");
            em.persist(employee);
            commitTransaction(em);
        } catch (RuntimeException ex) {
            if (isTransactionActive(em)) {
                rollbackTransaction(em);
            }

            closeEntityManager(em);
            throw ex;
        }

        version1 = employee.getVersion();

        try {
            beginTransaction(em);
            employee = em.find(Employee.class, employee.getId(), LockModeType.PESSIMISTIC_FORCE_INCREMENT);
            commitTransaction(em);

            assertTrue("The version was not updated on the pessimistic lock.", version1 < employee.getVersion());
        } catch (RuntimeException ex) {
            if (isTransactionActive(em)) {
                rollbackTransaction(em);
            }

            throw ex;
        } finally {
            closeEntityManager(em);
        }
    }

    public void testPESSIMISTIC_READLockWithNoChanges() {
        // Cannot create parallel entity managers in the server.
        if (isOnServer() || !isSelectForUpateSupported()) {
            return;
        }
        if ((JUnitTestCase.getServerSession()).getPlatform().isHANA()) {
            // HANA currently doesn't support pessimistic locking with queries on multiple tables
            // feature is under development (see bug 384129), but test should be skipped for the time being
            return;
        }
        Employee employee = null;
        Integer version1;

        EntityManager em = createEntityManager();

        try {
            beginTransaction(em);
            employee = new Employee();
            employee.setFirstName("Black");
            employee.setLastName("Crappie");
            em.persist(employee);
            commitTransaction(em);
        } catch (RuntimeException ex) {
            if (isTransactionActive(em)) {
                rollbackTransaction(em);
            }

            closeEntityManager(em);
            throw ex;
        }

        version1 = employee.getVersion();

        try {
            beginTransaction(em);
            employee = em.find(Employee.class, employee.getId(), LockModeType.PESSIMISTIC_READ);
            commitTransaction(em);

            assertTrue("The version was updated on the pessimistic lock.", version1.intValue() == employee.getVersion().intValue());
        } catch (RuntimeException ex) {
            if (isTransactionActive(em)) {
                rollbackTransaction(em);
            }

            throw ex;
        } finally {
            closeEntityManager(em);
        }
    }

    public void testPESSIMISTIC_WRITELockWithNoChanges() {
        // Cannot create parallel entity managers in the server.
        if (isOnServer() || !isSelectForUpateSupported()) {
            return;
        }
        if ((JUnitTestCase.getServerSession()).getPlatform().isHANA()) {
            // HANA currently doesn't support pessimistic locking with queries on multiple tables
            // feature is under development (see bug 384129), but test should be skipped for the time being
            return;
        }
        Employee employee = null;
        Integer version1;

        EntityManager em = createEntityManager();

        try {
            beginTransaction(em);
            employee = new Employee();
            employee.setFirstName("Black");
            employee.setLastName("Crappie");
            em.persist(employee);
            commitTransaction(em);
        } catch (RuntimeException ex) {
            if (isTransactionActive(em)) {
                rollbackTransaction(em);
            }

            closeEntityManager(em);
            throw ex;
        }

        version1 = employee.getVersion();

        try {
            beginTransaction(em);
            employee = em.find(Employee.class, employee.getId(), LockModeType.PESSIMISTIC_WRITE);
            commitTransaction(em);

            assertTrue("The version was updated on the pessimistic lock.", version1.intValue() == employee.getVersion().intValue());
        } catch (RuntimeException ex) {
            if (isTransactionActive(em)) {
                rollbackTransaction(em);
            }

            throw ex;
        } finally {
            closeEntityManager(em);
        }
    }

    public void testPESSIMISTIC_READ_TIMEOUTLock() {
        ServerSession session = JUnitTestCase.getServerSession();

        // Cannot create parallel entity managers in the server.
        // Lock timeout is only supported on Oracle.
        if (! isOnServer() && session.getPlatform().isOracle()) {
            EntityManager em = createEntityManager();
            List result = em.createQuery("Select employee from Employee employee").getResultList();
            Employee employee = (Employee) result.get(0);
            Exception lockTimeOutException = null;

            try {
                beginTransaction(em);
                employee = em.find(Employee.class, employee.getId(), LockModeType.PESSIMISTIC_READ);

                EntityManager em2 = createEntityManager();

                try {
                    beginTransaction(em2);

                    HashMap<String, Object> properties = new HashMap<String, Object>();
                    properties.put(QueryHints.PESSIMISTIC_LOCK_TIMEOUT, 5000);
                    Employee employee2 = em2.find(Employee.class, employee.getId(), LockModeType.PESSIMISTIC_READ, properties);
                    employee2.setFirstName("Invalid Lock Employee");
                    commitTransaction(em2);
                } catch (PersistenceException ex) {
                    if (isTransactionActive(em2)) {
                        rollbackTransaction(em2);
                    }
                    if (ex instanceof jakarta.persistence.LockTimeoutException) {
                        lockTimeOutException = ex;
                    } else {
                        throw ex;
                    }
                } finally {
                    closeEntityManager(em2);
                }

                commitTransaction(em);
            } catch (RuntimeException ex) {
                if (isTransactionActive(em)) {
                    rollbackTransaction(em);
                }

                throw ex;
            } finally {
                closeEntityManager(em);
            }

            assertFalse("Proper exception not thrown when Query with LockModeType.PESSIMISTIC is used.", lockTimeOutException == null);
        }
    }

    public void testPESSIMISTIC_WRITE_TIMEOUTLock() {
        ServerSession session = JUnitTestCase.getServerSession();

        // Cannot create parallel entity managers in the server.
        // Lock timeout is only supported on Oracle.
        if (! isOnServer() && session.getPlatform().isOracle()) {
            EntityManager em = createEntityManager();
            List result = em.createQuery("Select employee from Employee employee").getResultList();
            Employee employee = (Employee) result.get(0);
            Exception lockTimeOutException = null;

            try {
                beginTransaction(em);
                employee = em.find(Employee.class, employee.getId(), LockModeType.PESSIMISTIC_WRITE);

                EntityManager em2 = createEntityManager();

                try {
                    beginTransaction(em2);

                    HashMap<String, Object> properties = new HashMap<String, Object>();
                    properties.put(QueryHints.PESSIMISTIC_LOCK_TIMEOUT, 5000);
                    Employee employee2 = em2.find(Employee.class, employee.getId(), LockModeType.PESSIMISTIC_WRITE, properties);
                    employee2.setFirstName("Invalid Lock Employee");
                    commitTransaction(em2);
                } catch (PersistenceException ex) {
                    if (isTransactionActive(em2)) {
                        rollbackTransaction(em2);
                    }
                    if (ex instanceof jakarta.persistence.LockTimeoutException) {
                        lockTimeOutException = ex;
                    } else {
                        throw ex;
                    }
                } finally {
                    closeEntityManager(em2);
                }

                commitTransaction(em);
            } catch (RuntimeException ex) {
                if (isTransactionActive(em)) {
                    rollbackTransaction(em);
                }

                throw ex;
            } finally {
                closeEntityManager(em);
            }

            assertFalse("Proper exception not thrown when Query with LockModeType.PESSIMISTIC is used.", lockTimeOutException == null);
        }
    }

    public void testPESSIMISTIC_FORCE_INCREMENTLockOnNonVersionedEntity() {
        Department dept = null;

        EntityManager em = createEntityManager();
        try {
            beginTransaction(em);
            dept = new Department();
            em.persist(dept);
            commitTransaction(em);
        } catch (RuntimeException ex) {
            if (isTransactionActive(em)) {
                rollbackTransaction(em);
            }
            closeEntityManager(em);
            throw ex;
        }

        try {
            beginTransaction(em);
            dept = em.find(Department.class, dept.getId(), LockModeType.PESSIMISTIC_FORCE_INCREMENT);
            rollbackTransaction(em);
            fail("An Expected jakarta.persistence.PersistenceException was not thrown");
        } catch (PersistenceException ex) {
            if (isTransactionActive(em)) {
                rollbackTransaction(em);
            }
        } finally {
            if (isTransactionActive(em)) {
                rollbackTransaction(em);
            }
            closeEntityManager(em);
        }
    }

    public void testLockWithJoinedInheritanceStrategy () throws InterruptedException {
        if(getServerSession().getPlatform().isMaxDB()) {
            // skip this test (bug 326799)
            return;
        }

        // Cannot create parallel entity managers in the server.
        if (! isOnServer() && isSelectForUpateNoWaitSupported()) {
            Employee emp = null;
            LargeProject largeProject = null;

            EntityManager em = createEntityManager();

            try {
                beginTransaction(em);
                emp = new Employee();
                largeProject = new LargeProject();
                largeProject.setName("Large Project");
                largeProject.setBudget(50000);
                emp.addProject(largeProject);
                em.persist(emp);
                commitTransaction(em);
            } catch (RuntimeException ex) {
                if (isTransactionActive(em)) {
                    rollbackTransaction(em);
                }
                closeEntityManager(em);
                throw ex;
            }

            try {
                beginTransaction(em);
                emp = em.find(Employee.class, emp.getId());
                final Project lp1 = emp.getProjects().iterator().next();
                em.lock(lp1, LockModeType.PESSIMISTIC_WRITE);
                lp1.setName("Lock In Additional Table ");

                Runnable runnable = new Runnable() {

                    @Override
                    public void run() {
                        EntityManager em2 = createEntityManager();

                        try {
                            beginTransaction(em2);
                            LargeProject lp2 = em2.find(LargeProject.class, lp1.getId());
                            HashMap properties = new HashMap();
                            // According to the spec a 0 indicates a NOWAIT clause.
                            properties.put(QueryHints.PESSIMISTIC_LOCK_TIMEOUT, 0);
                            em2.lock(lp2, LockModeType.PESSIMISTIC_WRITE, properties);
                        } catch (PersistenceException ex) {
                            if (!(ex instanceof jakarta.persistence.PessimisticLockException)) {
                                throw ex;
                            }
                        } finally {
                            rollbackTransaction(em2);
                            closeEntityManager(em2);
                        }

                    }

                };

                Thread t2 = new Thread(runnable);
                t2.start();

                Thread.sleep(3000);

                // t2 should have failed to get a lock with NOWAIT and hence should have finished by now
                boolean hanging = t2.isAlive();

                if (hanging) {
                    t2.interrupt();
                }

                commitTransaction(em);

                assertFalse("pessimistic lock with nowait on entity with joined inheritance causes concurrent thread to wait", hanging);
            } catch (RuntimeException ex) {
                if (isTransactionActive(em)) {
                    rollbackTransaction(em);
                }

                throw ex;
            } finally {
                closeEntityManager(em);
            }

        } else {
            warning("Can't run this test because SELECT FOR UPDATE NO WAIT is not supported on this platform");
        }
    }

    /*
     * Helper class for testPESSIMISTIC_ExtendedScope.
     * Kills transaction that is holding the test for too long.
     */
    class TransactionKiller extends Thread {
        EntityManager em;
        long timeToWait;
        boolean shouldKillTransaction = true;
        boolean isWaiting;
        boolean hasKilledTransaction;
        TransactionKiller(EntityManager em, long timeToWait) {
            this.em = em;
            this.timeToWait = timeToWait;
        }
        @Override
        public void run() {
            try {
                isWaiting = true;
                Thread.sleep(timeToWait);
            } catch (InterruptedException ex) {
                throw new TestProblemException("TestProblem: TransactionKiller.run: wait failed: " + ex);
            } finally {
                isWaiting = false;
            }
            if (shouldKillTransaction && isTransactionActive(em)) {
                hasKilledTransaction = true;
                rollbackTransaction(em);
            }
        }
    }
    public void testPESSIMISTIC_ExtendedScope() {
        ServerSession session = JUnitTestCase.getServerSession();
        // Cannot create parallel entity managers in the server. Uses FOR UPDATE clause which SQLServer doesn't support.
        if (isOnServer() || !isSelectForUpateSupported() || !isPessimisticWriteLockSupported()) {
            return;
        }
        if ((JUnitTestCase.getServerSession()).getPlatform().isHANA()) {
            // HANA currently doesn't support pessimistic locking with queries on multiple tables
            // feature is under development (see bug 384129), but test should be skipped for the time being
            return;
        }

        ServerSession ss = ((JpaEntityManagerFactory)getEntityManagerFactory()).getServerSession();

        // If FOR UPDATE NOWAIT is not supported then FOR UPDATE is used - and that could lock the test (em2) for a long time (depending on db setting).
        boolean shouldSpawnThread = !isSelectForUpateNoWaitSupported();
        // To avoid that a separate thread is spawned that - after waiting the specified time -
        // completes the locking transaction (em1) and therefore clears the way to em2 go ahead.
        long timeToWait = 1000;

        String errorMsg = "";
        LockModeType lockMode = LockModeType.PESSIMISTIC_WRITE;

        // create Employee with Projects and Responsibilities
        Employee emp = new Employee();
        emp.setFirstName("PESSIMISTIC");
        emp.setLastName("ExtendedScope");
        emp.addResponsibility("0");
        emp.addResponsibility("1");
        SmallProject smallProject = new SmallProject();
        smallProject.setName("SmallExtendedScope");
        emp.addProject(smallProject);
        LargeProject largeProject = new LargeProject();
        largeProject.setName("LargeExtendedScope");
        largeProject.setBudget(5000);
        emp.addProject(largeProject);
        // persist
        EntityManager em = createEntityManager();
        try {
            beginTransaction(em);
            em.persist(emp);
            commitTransaction(em);
        } finally {
            if (isTransactionActive(em)) {
                rollbackTransaction(em);
            }
            closeEntityManager(em);
        }
        // cache ids
        int id = emp.getId();
        int smallProjId = smallProject.getId();

        clearCache();


        // properties to be passed to find, lock, refresh methods
        Map<String, Object> properties = new HashMap();
        properties.put(QueryHints.PESSIMISTIC_LOCK_SCOPE, PessimisticLockScope.EXTENDED);
        String forUpdateClause = session.getPlatform().getSelectForUpdateString();
        if(isSelectForUpateNoWaitSupported()) {
            properties.put(QueryHints.PESSIMISTIC_LOCK_TIMEOUT, 0);
            forUpdateClause = session.getPlatform().getSelectForUpdateNoWaitString();
        }
        String lockingClauseAfterWhereClause = "";
        String lockingClauseBeforeWhereClause = "";
        if(session.getPlatform().shouldPrintLockingClauseAfterWhereClause()) {
            lockingClauseAfterWhereClause = forUpdateClause;
        } else {
            lockingClauseBeforeWhereClause = forUpdateClause;
        }

        // indicates whether the object to be locked is already in cache.
        boolean[] isObjectCached = {false, true};
        // indicates which method on the first entity manager is used to lock the object.
        String[] testModeArray1 = {"query", "find", "lock", "refresh"};
        // indicates which method on the second entity manager is used to test the lock.
        String[] testModeArray2 = {"query", "find", "update_name", "update_salary", "remove_project", "remove_respons", "update_project", "update_respons", "lock", "refresh"};
        if (usesSOP()) {
            // if SOP is used there is no expected exceptions for remove_respons and update_respons because responsibilities read from sopObject, not from db row directly.
            // Therefore exclude remove_respons and update_respons.
            testModeArray2 = new String[]{"query", "find", "update_name", "update_salary", "remove_project", "update_project", "lock", "refresh"};
        }
/* test runs all combinations of elements of the above three arrays. To limit the number of configuration for debugging override these array, for instance:
        boolean[] isObjectCached = {false};
        String[] testModeArray1 = {"lock"};
        String[] testModeArray2 = {"find"};
*/
        // testMode1 loop
        for(int i=0; i < testModeArray1.length; i++) {
            String testMode1 = testModeArray1[i];
            // isObjectCached loop
            for(int k=0; k < isObjectCached.length; k++) {
                boolean isObjCached = isObjectCached[k];
                // testMode2 loop
                for(int j=0; j < testModeArray2.length; j++) {
                    String testMode2 = testModeArray2[j];
                    boolean isExceptionExpected = !testMode2.equals("update_project");

                    // lock emp using em1
                    EntityManager em1= createEntityManager();
                    // bring object into cache if required
                    if(isObjCached) {
                        ss.log(SessionLog.FINEST, SessionLog.QUERY, "testPESSIMISTIC_ExtendedScope: bring object into cache", null, null, false);
                        em1.find(Employee.class, id);
                    }
                    Employee emp1;
                    try {
                        beginTransaction(em1);

                        ss.log(SessionLog.FINEST, SessionLog.QUERY, "testPESSIMISTIC_ExtendedScope: testMode1 = " + testMode1, null, null, false);

                        if(testMode1.equals("query")) {
                            Query query1 = em1.createQuery("SELECT emp FROM Employee emp WHERE emp.id = "+id).setLockMode(lockMode).
                                    setHint(QueryHints.PESSIMISTIC_LOCK_SCOPE, PessimisticLockScope.EXTENDED);
                            if(isSelectForUpateNoWaitSupported()) {
                                query1.setHint(QueryHints.PESSIMISTIC_LOCK_TIMEOUT, 0);
                            }
                            emp1 = (Employee)query1.getSingleResult();
                        } else if(testMode1.equals("find")) {
                            emp1 = em1.find(Employee.class, id, lockMode, properties);
                        } else {
                            emp1 = em1.find(Employee.class, id);
                            if(testMode1.equals("lock")) {
                                em1.lock(emp1, lockMode, properties);
                            } else if(testMode1.equals("refresh")) {
                                em1.refresh(emp1, lockMode, properties);
                            } else {
                                fail("Unknown testMode1 = " + testMode1);
                            }
                        }

                        TransactionKiller transactionKiller = null;
                        // try to update emp using em2
                        EntityManager em2 = createEntityManager();
                        Employee emp2;
                        try {
                            beginTransaction(em2);

                            ss.log(SessionLog.FINEST, SessionLog.QUERY, "testPESSIMISTIC_ExtendedScope: testMode2 = " + testMode2, null, null, false);

                            if(shouldSpawnThread) {
                                // after waiting TransactionKiller rollback em1 transaction unlocking way for em2 to proceed.
                                // the test assumes that em2 waiting for timeToWait means em2 waiting on the lock acquired by em1.
                                transactionKiller = new TransactionKiller(em1, timeToWait);
                                transactionKiller.start();
                            }

                            if(testMode2.equals("query")) {
                                Query query2 = em2.createQuery("SELECT emp FROM Employee emp WHERE emp.id = "+id).setLockMode(lockMode).
                                setHint(QueryHints.PESSIMISTIC_LOCK_SCOPE, PessimisticLockScope.EXTENDED);
                                if(isSelectForUpateNoWaitSupported()) {
                                    query2.setHint(QueryHints.PESSIMISTIC_LOCK_TIMEOUT, 0);
                                }
                                emp2 = (Employee)query2.getSingleResult();
                            } else if(testMode2.equals("find")) {
                                emp2 = em2.find(Employee.class, id, lockMode, properties);
                            } else if(testMode2.equals("update_name")) {
                                em2.createNativeQuery("SELECT L_NAME FROM CMP3_EMPLOYEE"+lockingClauseBeforeWhereClause+" WHERE EMP_ID = "+id+lockingClauseAfterWhereClause).getSingleResult();
//                                em2.createNativeQuery("UPDATE CMP3_EMPLOYEE SET L_NAME = 'NEW' WHERE EMP_ID = "+id).executeUpdate();
                            } else if(testMode2.equals("update_salary")) {
                                em2.createNativeQuery("SELECT SALARY FROM CMP3_SALARY"+lockingClauseBeforeWhereClause+" WHERE EMP_ID = "+id+lockingClauseAfterWhereClause).getSingleResult();
//                                em2.createNativeQuery("UPDATE CMP3_SALARY SET SALARY = 1000 WHERE EMP_ID = "+id).executeUpdate();
                            } else if(testMode2.equals("remove_project")) {
                                em2.createNativeQuery("SELECT PROJECTS_PROJ_ID FROM CMP3_EMP_PROJ"+lockingClauseBeforeWhereClause+" WHERE EMPLOYEES_EMP_ID = "+id+lockingClauseAfterWhereClause).getResultList();
//                                em2.createNativeQuery("DELETE FROM CMP3_EMP_PROJ WHERE EMPLOYEES_EMP_ID = "+id).executeUpdate();
                            } else if(testMode2.equals("remove_respons")) {
                                em2.createNativeQuery("SELECT EMP_ID FROM CMP3_RESPONS"+lockingClauseBeforeWhereClause+" WHERE EMP_ID = "+id+lockingClauseAfterWhereClause).getResultList();
//                                em2.createNativeQuery("DELETE FROM CMP3_RESPONS WHERE EMP_ID = "+id).executeUpdate();
                            } else if(testMode2.equals("update_project")) {
                                em2.createNativeQuery("SELECT PROJ_NAME FROM CMP3_PROJECT"+lockingClauseBeforeWhereClause+" WHERE PROJ_ID = "+smallProjId+lockingClauseAfterWhereClause).getSingleResult();
//                                em2.createNativeQuery("UPDATE CMP3_PROJECT SET PROJ_NAME = 'NEW' WHERE PROJ_ID = "+smallProjId).executeUpdate();
                            } else if(testMode2.equals("update_respons")) {
                                em2.createNativeQuery("SELECT DESCRIPTION FROM CMP3_RESPONS"+lockingClauseBeforeWhereClause+" WHERE EMP_ID = "+id+lockingClauseAfterWhereClause).getResultList();
//                                em2.createNativeQuery("UPDATE CMP3_RESPONS SET DESCRIPTION = 'NEW' WHERE EMP_ID = "+id).executeUpdate();
                            } else {
                                emp2 = em2.find(Employee.class, id);
                                if(testMode2.equals("lock")) {
                                    em2.lock(emp2, lockMode, properties);
                                } else if(testMode2.equals("refresh")) {
                                    em2.refresh(emp2, lockMode, properties);
                                } else {
                                    fail("Unknown testMode2 = " + testMode2);
                                }
                            }

            //                commitTransaction(em2);
                            boolean hasKilledTransaction = false;
                            if(transactionKiller != null) {
                                transactionKiller.shouldKillTransaction = false;
                                try {
                                    transactionKiller.join();
                                } catch(InterruptedException intEx) {
                                    // Ignore
                                }
                                hasKilledTransaction = transactionKiller.hasKilledTransaction;
                            }
                            // transaction killed by TransactionKiller is treated as PessimisticLockException
                            if(isExceptionExpected && !hasKilledTransaction) {
                                String localErrorMsg = testMode1 + (isObjCached ? " cached " : " ") + testMode2 + ": Exception was expected.";
                                ss.log(SessionLog.FINEST, SessionLog.QUERY, localErrorMsg, null, null, false);
                                errorMsg += '\n' + localErrorMsg;
                            }
                        } catch (Exception ex) {
                            if(transactionKiller != null) {
                                transactionKiller.shouldKillTransaction = false;
                                try {
                                    transactionKiller.join();
                                } catch(InterruptedException intEx) {
                                    // Ignore
                                }
                            }
                            if(!isExceptionExpected) {
                                String localErrorMsg = testMode1 + (isObjCached ? " cached " : " ") + testMode2 + ": Unexpected exception: " + ex.getMessage();
                                ss.log(SessionLog.FINEST, SessionLog.QUERY, localErrorMsg, null, null, false);
                                errorMsg += '\n' + localErrorMsg;
                            }
                        } finally {
                            if (isTransactionActive(em2)) {
                                rollbackTransaction(em2);
                            }
                            closeEntityManager(em2);
                        }

            //            commitTransaction(em1);
                    } finally {
                        if (isTransactionActive(em1)) {
                            rollbackTransaction(em1);
                        }
                        closeEntityManager(em1);
                    }
                    clearCache();
                }  // testModel2 loop
            }  // isObjectCached loop
        }  // testMode1 loop

        // clean up
        em = createEntityManager();
        emp = em.find(Employee.class, id);
        try {
            beginTransaction(em);
            Iterator<Project> it = emp.getProjects().iterator();
            while(it.hasNext()) {
                Project project = it.next();
                it.remove();
                em.remove(project);
            }
            em.remove(emp);
            commitTransaction(em);
        } finally {
            if (isTransactionActive(em)) {
                rollbackTransaction(em);
            }
            closeEntityManager(em);
        }

        if(errorMsg.length() > 0) {
            fail(errorMsg);
        }
    }

    // test for bug 4676587:
    // CTS: AFTER A REMOVE THEN A PERSIST ON THE SAME ENTITY, CONTAINS RETURNS FALSE
    // The test performs persist, remove, persist sequence on a single object
    // in different "flavours":
    // doTransaction - the first persist happens in a separate transaction;
    // doFirstFlush - perform flush after the first persist;
    // doSecondFlush - perform flush after the remove;
    // doThirdFlush - perform flush after the second persist;
    // doRollback - rollbacks transaction that contains remove and the second persist.
    public void testPersistRemoved() {
        // create an Employee
        String firstName = "testPesistRemoved";
        Employee emp = new Employee();
        emp.setFirstName(firstName);

        // make sure no Employee with the specified firstName exists.
        EntityManager em = createEntityManager();
        beginTransaction(em);
        try{
            Query q = em.createQuery("SELECT e FROM Employee e WHERE e.firstName = '"+firstName+"'");
            for (Object oldData : q.getResultList()) {
                em.remove(oldData);
            }
            commitTransaction(em);
        }catch (RuntimeException ex){
            if (isTransactionActive(em)){
                rollbackTransaction(em);
            }
            closeEntityManager(em);
            throw ex;
        }

        String errorMsg = "";
        for (int i=0; i < 32; i++) {
            int j = i;
            boolean doRollback = j % 2 == 0;
            j = j/2;
            boolean doThirdFlush = j % 2 == 0;
            j = j/2;
            boolean doSecondFlush = j % 2 == 0;
            j = j/2;
            boolean doFirstFlush = j % 2 == 0;
            j = j/2;
            boolean doTransaction = j % 2 == 0;
            if(doTransaction && doFirstFlush) {
                continue;
            }
            String msg = "";
            if(doTransaction) {
                msg = "Transaction ";
            }
            if(doFirstFlush) {
                msg = msg + "firstFlush ";
            }
            if(doSecondFlush) {
                msg = msg + "secondFlush ";
            }
            if(doThirdFlush) {
                msg = msg + "thirdFlush ";
            }
            if(doRollback) {
                msg = msg + "RolledBack ";
            }

            String localErrorMsg = msg;
            boolean exceptionWasThrown = false;
            Integer empId = null;
            beginTransaction(em);
            try {
                emp = new Employee();
                emp.setFirstName(firstName);

                // persist the Employee
                em.persist(emp);
                if(doTransaction) {
                    commitTransaction(em);
                    empId = emp.getId();
                    beginTransaction(em);
                } else {
                    if(doFirstFlush) {
                        em.flush();
                    }
                }

                if(doTransaction) {
                    emp = em.find(Employee.class, empId);
                }
                // remove the Employee
                em.remove(emp);
                if(doSecondFlush) {
                    em.flush();
                }

                // persist the Employee
                em.persist(emp);
                if(doThirdFlush) {
                    em.flush();
                }
            } catch (RuntimeException ex) {
                rollbackTransaction(em);
                localErrorMsg = localErrorMsg + " " + ex.getMessage() + ";";
                exceptionWasThrown = true;
            }

            boolean employeeShouldExist = doTransaction || !doRollback;
            boolean employeeExists = false;
            try{
                if(!exceptionWasThrown) {
                    if(doRollback) {
                        rollbackTransaction(em);
                    } else {
                        commitTransaction(em);
                    }

                    if(doTransaction) {
                        Employee employeeReadFromCache = em.find(Employee.class, empId);
                        if(employeeReadFromCache == null) {
                            localErrorMsg = localErrorMsg + " employeeReadFromCache == null;";
                        }
                    }

                    List resultList = em.createQuery("SELECT OBJECT(e) FROM Employee e WHERE e.firstName = '"+firstName+"'").getResultList();
                    employeeExists = resultList.size() > 0;

                    if(employeeShouldExist) {
                        if(resultList.size() > 1) {
                            localErrorMsg = localErrorMsg + " resultList.size() > 1";
                        }
                        if(!employeeExists) {
                            localErrorMsg = localErrorMsg + " employeeReadFromDB == null;";
                        }
                    } else {
                        if(resultList.size() > 0) {
                            localErrorMsg = localErrorMsg + " employeeReadFromDB != null;";
                        }
                    }
                }
            }catch (RuntimeException ex){
                if (isTransactionActive(em)){
                    rollbackTransaction(em);
                }
                throw ex;
            }

            // clean up
            if(employeeExists || exceptionWasThrown) {
                em = createEntityManager();
                beginTransaction(em);
                try{
                    Query q = em.createQuery("SELECT e FROM Employee e WHERE e.firstName = '"+firstName+"'");
                    for (Object oldData : q.getResultList()) {
                        em.remove(oldData);
                    }
                    commitTransaction(em);
                }catch (RuntimeException ex){
                    rollbackTransaction(em);
                    throw ex;
                }
            }

            if(!msg.equals(localErrorMsg)) {
                errorMsg = errorMsg + "i="+Integer.toString(i)+": "+ localErrorMsg + " ";
            }
        }
        if(errorMsg.length() > 0) {
            fail(errorMsg);
        }
    }

    public void testPersistManagedException(){
        EntityManager em = createEntityManager();
        beginTransaction(em);
        Employee emp = new Employee();
        emp.setFirstName("PersistManagedException");
        em.persist(emp);
        em.flush();
        Integer id = emp.getId();
        emp = new Employee();
        emp.setId(id);
        boolean caughtException = false;
        try{
            em.persist(emp);
        } catch (EntityExistsException e){
            caughtException = true;
        }
        //bug240061: cannot operate on a closed/rolledback transaction in JBOSS - JBOSS's proxy throws away the old one and will
        // attempt to get a new EM.  An exception is thrown when this new EM tries to register with the transaction
        //emp = em.find(Employee.class, id);
        //em.remove(emp);
        rollbackTransaction(em);
        assertTrue("EntityExistsException was not thrown for an existing Employee.", caughtException);
    }

    public void testPersistManagedNoException(){
        EntityManager em = createEntityManager();
        beginTransaction(em);
        Employee emp = new Employee();
        em.persist(emp);
        em.flush();
        Integer id = emp.getId();
        Address address = new Address();
        emp.setAddress(address);
        boolean caughtException = false;
        try{
            em.persist(emp);
        } catch (EntityExistsException e){
            caughtException = true;
        }
        emp = em.find(Employee.class, id);
        em.remove(emp);
        commitTransaction(em);
        assertFalse("EntityExistsException was thrown for a registered Employee.", caughtException);
    }

    public void testDetachManagedObject() {
        EntityManager em = createEntityManager();

        // create test data
        beginTransaction(em);
        Employee emp = new Employee();
        emp.setFirstName("beforePersist");
        em.persist(emp);
        Integer id = emp.getId();
        commitTransaction(em);

        // Test that 'detach()' removes 'emp' from the persistence context
        beginTransaction(em);
        em.detach(emp);
        assertFalse("could not detach managed object", em.contains(emp));

        // clean up
        emp = em.find(Employee.class, id);
        em.remove(emp);
        commitTransaction(em);
    }

    public void testCascadeDetach() {
        EntityManager em = createEntityManager();
        beginTransaction(em);
        try {
            Employee emp = (Employee)em.createQuery("Select e from Employee e where e.managedEmployees is not empty").getResultList().get(0);
            emp.getManagedEmployees().size();
            em.detach(emp);
            assertFalse("Did not cascade detach", em.contains(emp.getManagedEmployees().iterator().next()));
        } finally {
            closeEntityManagerAndTransaction(em);
        }
    }

    //detaching an non-managed object should not throw any exception.
    public void testDetachNonManagedObject() {
        EntityManager em = createEntityManager();

        // Create test data
        beginTransaction(em);
        Employee emp = new Employee();
        emp.setFirstName("beforePersist");
        boolean caughtException = false;

        // detach the object
        em.detach(emp);
        em.persist(emp);

        // Deleting the object
        em.remove(emp);
        commitTransaction(em);
        assertFalse("Cannot_detach_Object Exception was thrown for a non-managed Entity", caughtException);
    }

    // test for bug 4676587:
    // CTS: AFTER A REMOVE THEN A PERSIST ON THE SAME ENTITY, CONTAINS RETURNS FALSE
    public void testRemoveFlushPersistContains() {
        // create an Employee
        String firstName = "testRemoveFlushPersistContains";
        Employee emp = new Employee();
        emp.setFirstName(firstName);

        // make sure no Employee with the specified firstName exists.
        EntityManager em = createEntityManager();
        beginTransaction(em);
        try{
            Query q = em.createQuery("SELECT e FROM Employee e WHERE e.firstName = '"+firstName+"'");
            for (Object oldData : q.getResultList()) {
                em.remove(oldData);
            }
            commitTransaction(em);
        }catch (RuntimeException ex){
            if (isTransactionActive(em)){
                rollbackTransaction(em);
            }
            closeEntityManager(em);
            throw ex;
        }

        // persist
        beginTransaction(em);
        try{
            em.persist(emp);
            commitTransaction(em);
        }catch (RuntimeException ex){
            if (isTransactionActive(em)){
                rollbackTransaction(em);
            }
            closeEntityManager(em);
            throw ex;
        }
        // remove, flush, persist, contains
        boolean contains = false;
        beginTransaction(em);
        try{
            emp = em.find(Employee.class, emp.getId());
            em.remove(emp);
            em.flush();
            em.persist(emp);
            contains = em.contains(emp);
            commitTransaction(em);
        }catch (RuntimeException ex){
            if (isTransactionActive(em)){
                rollbackTransaction(em);
            }
            closeEntityManager(em);
            throw ex;
        }

        // clean up
        beginTransaction(em);
        try{
            emp = em.find(Employee.class, emp.getId());
            em.remove(emp);
            commitTransaction(em);
        }catch (RuntimeException ex){
            if (isTransactionActive(em)){
                rollbackTransaction(em);
            }
            closeEntityManager(em);
            throw ex;
        }

        assertTrue("contains==false", contains);
    }

    // test for bug 4742161:
    // CTS: OBJECTS REMOVED AND THEN FLUSHED ARE RETURNED BY QUERIES AFTER THE FLUSH
    public void testRemoveFlushFind() {
        // create an Employee
        String firstName = "testRemoveFlushFind";
        Employee emp = new Employee();
        emp.setFirstName(firstName);

        // make sure no Employee with the specified firstName exists.
        EntityManager em = createEntityManager();
        beginTransaction(em);
        try{
            Query q = em.createQuery("SELECT e FROM Employee e WHERE e.firstName = '"+firstName+"'");
            for (Object oldData : q.getResultList()) {
                em.remove(oldData);
            }
            commitTransaction(em);
        }catch (RuntimeException ex){
            if (isTransactionActive(em)){
                rollbackTransaction(em);
            }
            closeEntityManager(em);
            throw ex;
        }

        // persist
        beginTransaction(em);
        try{
            em.persist(emp);
            commitTransaction(em);
        }catch (RuntimeException ex){
            if (isTransactionActive(em)){
                rollbackTransaction(em);
            }
            closeEntityManager(em);
            throw ex;
        }

        // remove, flush, persist, contains
        boolean foundAfterFlush = true;
        boolean foundBeforeFlush = true;
        beginTransaction(em);
        try{
            emp = em.find(Employee.class, emp.getId());
            em.remove(emp);
            Employee empFound = em.find(Employee.class, emp.getId());
            foundBeforeFlush = empFound != null;
            em.flush();
            empFound = em.find(Employee.class, emp.getId());
             foundAfterFlush = empFound != null;
            commitTransaction(em);
        }catch (RuntimeException ex){
            if (isTransactionActive(em)){
                rollbackTransaction(em);
            }
            closeEntityManager(em);
            throw ex;
        }

        // clean up
        beginTransaction(em);
        try{
            Query q = em.createQuery("SELECT e FROM Employee e WHERE e.firstName = '"+firstName+"'");
            for (Object oldData : q.getResultList()) {
                em.remove(oldData);
            }
            commitTransaction(em);
        }catch (RuntimeException ex){
            if (isTransactionActive(em)){
                rollbackTransaction(em);
            }
            closeEntityManager(em);
            throw ex;
        }

        assertFalse("removed object found", foundBeforeFlush);
        assertFalse("removed object found after flush", foundAfterFlush);
    }

    // Test that deleting an employee works correctly.
    public void testDeleteEmployee() {
        Employee employee = new Employee();
        employee.addPhoneNumber(new PhoneNumber("home", "123", "4567"));
        employee.addPhoneNumber(new PhoneNumber("fax", "456", "4567"));
        employee.addResponsibility("work hard");
        employee.addResponsibility("write code");
        employee.addProject(new Project());
        employee.setWorkWeek(new HashSet<Employee.Weekdays>());
        employee.getWorkWeek().add(Employee.Weekdays.MONDAY);
        employee.getWorkWeek().add(Employee.Weekdays.TUESDAY);
        QuerySQLTracker counter = new QuerySQLTracker(getServerSession());
        EntityManager em = createEntityManager();
        try {
            beginTransaction(em);
            em.persist(employee);
            commitTransaction(em);
            closeEntityManager(em);
            clearCache();
            em = createEntityManager();
            beginTransaction(em);
            employee = em.find(Employee.class, employee.getId());
            counter.getSqlStatements().clear();
            em.remove(employee);
            commitTransaction(em);
            if (isWeavingEnabled() && counter.getSqlStatements().size() > 13) {
                fail("Only 13 sql statements should have occured:" + counter.getSqlStatements().size());
            }
            beginTransaction(em);
            verifyDelete(employee);
            commitTransaction(em);
        } finally {
            if (isTransactionActive(em)) {
                rollbackTransaction(em);
            }
            if (counter != null) {
                counter.remove();
            }
            closeEntityManager(em);
        }
    }

    // Test deletion does not violate constraints.
    public void testDeleteEverything() {
        EntityManager em = createEntityManager();
        try {
            EmployeePopulator employeePopulator = new EmployeePopulator();
            employeePopulator.buildExamples();
            employeePopulator.employeeExample1().setManager(employeePopulator.employeeExample1());
            employeePopulator.employeeExample2().setManager(employeePopulator.employeeExample3());
            employeePopulator.employeeExample3().setManager(employeePopulator.employeeExample2());
            em.clear();
            clearCache();
            employeePopulator.persistExample(getDatabaseSession());

            beginTransaction(em);
            em.setFlushMode(FlushModeType.COMMIT);
            for (Object each : em.createQuery("Select e from Employee e").getResultList()) {
                em.remove(each);
            }
            for (Object each : em.createQuery("Select p from Project p").getResultList()) {
                em.remove(each);
            }
            for (Object each : em.createQuery("Select d from ADV_DEPT d").getResultList()) {
                em.remove(each);
            }
            commitTransaction(em);
            closeEntityManager(em);

            // This time clear the cache first.
            employeePopulator = new EmployeePopulator();
            employeePopulator.buildExamples();
            employeePopulator.persistExample(getDatabaseSession());
            clearCache();
            em = createEntityManager();
            beginTransaction(em);
            em.setFlushMode(FlushModeType.COMMIT);
            for (Object each : em.createQuery("Select e from Employee e").getResultList()) {
                em.remove(each);
            }
            for (Object each : em.createQuery("Select p from Project p").getResultList()) {
                em.remove(each);
            }
            for (Object each : em.createQuery("Select d from ADV_DEPT d").getResultList()) {
                em.remove(each);
            }
            commitTransaction(em);
        } finally {
            if (isTransactionActive(em)) {
                rollbackTransaction(em);
            }
            closeEntityManager(em);
        }
    }

    /**
     *     Test that deleting an employee works correctly.
     *     This test case was added in 8177 for 324321 and modified for 325605.
     *     The issue is that the status enum will be cascade deleted even if it is not
     *     instantiated (lazy) because the owning object does not know if the collection is empty
     *     without instantiating it.
     *     DB2 will therefore emit warning logs that are printed at FINEST in this lazy case.
     *     This test is a modification of testDeleteEmployee() that verifies instantiated lists are also ok
     *
     *     11/17/2010-2.2 Michael O'Brien
     *       - 325605: Filter out SQL warnings that are not SQL statements but are
     *       logged at a non-warning level.  This affects only implementors of SessionLog that
     *       perform log diagnostics/tracking in addition to logging.
     */
    public void testDeleteEmployee_with_status_enum_collection_instantiated() {
        Employee employee = new Employee();
        PhoneNumber homePhone = new PhoneNumber("home", "123", "4567");
        PhoneNumber faxPhone = new PhoneNumber("fax", "456", "4567");
        employee.addPhoneNumber(homePhone);
        employee.addPhoneNumber(faxPhone);
        employee.addResponsibility("work hard");
        employee.addResponsibility("write code");
        employee.addProject(new Project());
        employee.setWorkWeek(new HashSet<Employee.Weekdays>());
        employee.getWorkWeek().add(Employee.Weekdays.MONDAY);
        employee.getWorkWeek().add(Employee.Weekdays.TUESDAY);
        // set enums
        employee.setStatus(Employee.EmployeeStatus.PART_TIME); // enum index is 1
        // set enum on 1 of the 2 phones, leave the other Collection of enums unset - but do a later find to instantiate the Collection
        homePhone.addStatus(PhoneNumber.PhoneStatus.ASSIGNED);
        QuerySQLTracker counter = new QuerySQLTracker(getServerSession());
        EntityManager em = createEntityManager();
        try {
            beginTransaction(em);
            em.persist(employee);
            commitTransaction(em);
            closeEntityManager(em);
            clearCache();
            em = createEntityManager();
            beginTransaction(em);
            employee = em.find(Employee.class, employee.getId());
            // instantiate the empty Collection of enums to verify we do not cascade delete if we "know" the Collection is empty
            employee.getPhoneNumbers();
            counter.getSqlStatements().clear();
            em.remove(employee);
            commitTransaction(em);
            // We do not count any SQL warnings that may occur (DB2 may have 3) at the FINEST level
            if (isWeavingEnabled() && counter.getSqlStatements().size() > 13) {
                fail("Only 13 sql statements should have occured: " + counter.getSqlStatements().size());
            }
            beginTransaction(em);
            verifyDelete(employee);
            commitTransaction(em);
        } finally {
            if (isTransactionActive(em)) {
                rollbackTransaction(em);
            }
            if (counter != null) {
                counter.remove();
            }
            closeEntityManager(em);
        }
    }

    // Test that deleting an Man works correctly.
    public void testDeleteMan() {
        EntityManager em = createEntityManager();
        QuerySQLTracker counter = null;
        try {
            beginTransaction(em);
            Man man = new Man();
            em.persist(man);
            Woman woman = new Woman();
            em.persist(woman);
            PartnerLink link = new PartnerLink();
            em.persist(link);
            man.setPartnerLink(link);
            link.setMan(man);
            woman.setPartnerLink(link);
            link.setWoman(woman);
            commitTransaction(em);
            closeEntityManager(em);
            clearCache();
            counter = new QuerySQLTracker(getServerSession());
            em = createEntityManager();
            beginTransaction(em);
            // Count SQL.
            man = em.find(Man.class, man.getId());
            woman = em.find(Woman.class, woman.getId());
            woman.setPartnerLink(null);
            counter.getSqlStatements().clear();
            em.remove(man);
            commitTransaction(em);
            if (counter.getSqlStatements().size() > 2) {
                fail("Only 2 delete should have occured.");
            }
            beginTransaction(em);
            verifyDelete(man);
            commitTransaction(em);
        } finally {
            if (counter != null) {
                counter.remove();
            }
            if (isTransactionActive(em)) {
                rollbackTransaction(em);
            }
            closeEntityManager(em);
        }
    }

    // test for bug 4681287:
    // CTS: EXCEPTION EXPECTED ON FIND() IF PK PASSED IN != ATTRIBUTE TYPE
    public void testFindWithWrongTypePk() {
        EntityManager em = createEntityManager();
        try {
            em.find(Employee.class, "1");
        } catch (IllegalArgumentException ilEx) {
            return;
        } catch (Exception ex) {
            fail("Wrong exception thrown: " + ex.getMessage());
            return;
        }finally{
            closeEntityManager(em);
        }
        fail("No exception thrown");
    }

    //test for gf721 - IllegalArgumentException expected for null PK
    public void testFindWithNullPk() {
        EntityManager em = createEntityManager();
        try {
            em.find(Employee.class, null);
        } catch (IllegalArgumentException iae) {
            return;
        } catch (Exception e) {
            fail("Wrong exception type thrown: " + e.getClass());
        }finally{
            closeEntityManager(em);
        }
        fail("No exception thrown when null PK used in find operation.");
    }

    public void testFindWithProperties(){
        Employee employee = new Employee();
        employee.setFirstName("Marc");
        HashMap<String, Object> queryhints=new  HashMap<String, Object>();
        EntityManager em = createEntityManager();
        try {
          beginTransaction(em);
          em.persist(employee);
          em.flush();
          int empId=employee.getId();
          Employee e1=em.find(Employee.class,empId);
          e1.setFirstName("testfind");
          queryhints.put(QueryHints.REFRESH, "TRUE");
          Employee e2= em.find(Employee.class, empId, queryhints);
          assertFalse(e2.getFirstName().equals("testfind"));
          em.flush();
        } finally{
            closeEntityManagerAndTransaction(em);
        }
      }

    public void testCheckVersionOnMerge() {
        Employee employee = new Employee();
        employee.setFirstName("Marc");

        EntityManager em = createEntityManager();
        try{
            beginTransaction(em);
            em.persist(employee);
            commitTransaction(em);
            em.clear();
            beginTransaction(em);
            Employee empClone = em.find(Employee.class, employee.getId());
            empClone.setFirstName("Guy");
            commitTransaction(em);
        }catch (RuntimeException ex){
            if (isTransactionActive(em)){
                rollbackTransaction(em);
            }
            closeEntityManager(em);
            fail("Exception caught during test setup " + ex);
        }

        try {
            beginTransaction(em);
            em.merge(employee);
            commitTransaction(em);
        } catch (OptimisticLockException e) {
            rollbackTransaction(em);
            closeEntityManager(em);
            return;
        } catch (RuntimeException ex) {
            if (isTransactionActive(em)){
                rollbackTransaction(em);
            }
            closeEntityManager(em);
            fail("Wrong exception thrown: " + ex.getMessage());
        }

        fail("No exception thrown");
    }

    public void testClear(){
        Employee employee = new Employee();
        EntityManager em = createEntityManager();
        beginTransaction(em);
        try{
            em.persist(employee);
            commitTransaction(em);
            em.clear();
        }catch (RuntimeException ex){
            if (isTransactionActive(em)){
                rollbackTransaction(em);
            }
            closeEntityManager(em);
            throw ex;
        }
        boolean cleared = !em.contains(employee);
        closeEntityManager(em);
        assertTrue("EntityManager not properly cleared", cleared);
    }

    // Test using PERSISTENCE_CONTEXT_CLOSE_ON_COMMIT option to avoid the resume on commit.
    public void testCloseOnCommit() {
        // Properties only works in jse.
        if (isOnServer()) {
            return;
        }
        Map properties = new HashMap();
        properties.put(PersistenceUnitProperties.PERSISTENCE_CONTEXT_CLOSE_ON_COMMIT, "true");
        EntityManager em = createEntityManager(properties);
        beginTransaction(em);
        try {
            Employee emp = new Employee();
            emp.setFirstName("Douglas");
            emp.setLastName("McRae");
            em.persist(emp);
            commitTransaction(em);
            verifyObjectInCacheAndDatabase(emp);
            closeEntityManager(em);
            em = createEntityManager(properties);
            beginTransaction(em);
            emp = em.find(Employee.class, emp.getId());
            emp.setFirstName("Joe");
            commitTransaction(em);
            verifyObjectInCacheAndDatabase(emp);
            em = createEntityManager(properties);
            beginTransaction(em);
            emp = em.find(Employee.class, emp.getId());
            em.remove(emp);
            commitTransaction(em);
            closeEntityManager(em);
        } catch (RuntimeException exception) {
            if (isTransactionActive(em)){
                rollbackTransaction(em);
            }
            closeEntityManager(em);
            throw exception;
        }
    }

    // Test using PERSISTENCE_CONTEXT_PERSIST_ON_COMMIT option to avoid the discover on commit.
    public void testPersistOnCommit() {
        // Properties only works in jse.
        if (isOnServer()) {
            return;
        }
        Map properties = new HashMap();
        properties.put(PersistenceUnitProperties.PERSISTENCE_CONTEXT_PERSIST_ON_COMMIT, "false");
        EntityManager em = createEntityManager(properties);
        beginTransaction(em);
        try {
            Employee emp = new Employee();
            emp.setFirstName("Douglas");
            emp.setLastName("McRae");
            em.persist(emp);
            commitTransaction(em);
            verifyObjectInCacheAndDatabase(emp);
            closeEntityManager(em);
            em = createEntityManager(properties);
            beginTransaction(em);
            Address address = new Address();
            emp = em.find(Employee.class, emp.getId());
            emp.setAddress(address);
            em.persist(address);
            commitTransaction(em);
            verifyObjectInCacheAndDatabase(emp);
            em = createEntityManager(properties);
            beginTransaction(em);
            emp = em.find(Employee.class, emp.getId());
            em.remove(emp);
            commitTransaction(em);
            closeEntityManager(em);
        } catch (RuntimeException exception) {
            if (isTransactionActive(em)){
                rollbackTransaction(em);
            }
            closeEntityManager(em);
            throw exception;
        }
    }

    // Test Not using the persist operation on commit.
    public void testNoPersistOnCommit() {
        // Properties only works in jse.
        if (isOnServer()) {
            return;
        }
        EntityManager em = createEntityManager();
        beginTransaction(em);
        Employee employee = new Employee();
        employee.setLastName("SomeName");
        Address addr = new Address();
        addr.setCity("Douglas");
        try {
            em.persist(employee);
            commitTransaction(em);
            verifyObjectInCacheAndDatabase(employee);
            closeEntityManager(em);

            em = createEntityManager();
            beginTransaction(em);
            ((RepeatableWriteUnitOfWork)JpaHelper.getEntityManager(em).getUnitOfWork()).setDiscoverUnregisteredNewObjectsWithoutPersist(true);
            employee = em.find(Employee.class, employee.getId());
            employee.setAddress(addr);
            addr.getEmployees().add(employee);
            commitTransaction(em);
            verifyObjectInCacheAndDatabase(employee);
            closeEntityManager(em);

            em = createEntityManager();
            clearCache();
            beginTransaction(em);
            ((RepeatableWriteUnitOfWork)JpaHelper.getEntityManager(em).getUnitOfWork()).setDiscoverUnregisteredNewObjectsWithoutPersist(true);
            employee = em.find(Employee.class, employee.getId());
            employee.getAddress().setCountry("country");
            employee.getAddress().getEmployees().size();
            employee.setAddress((Address)null);
            em.remove(employee);
            commitTransaction(em);

            em = createEntityManager();
            beginTransaction(em);
            employee = em.find(Employee.class, employee.getId());
            assertNull("Employee Not Deleted", employee);
            commitTransaction(em);
            closeEntityManager(em);
        } catch (RuntimeException exception) {
            if (isTransactionActive(em)) {
                rollbackTransaction(em);
            }
            closeEntityManager(em);
            throw exception;
        } finally {
            try {
                em = createEntityManager();
                clearCache();
                beginTransaction(em);
                em.remove(em.find(Address.class, addr.getID()));
                commitTransaction(em);
            } catch (RuntimeException ex) {
                // ignore

            }
        }
    }

    // Test Not using the persist operation on commit.
    public void testNoPersistOnCommitProperties() {
        // Properties only works in jse.
        if (isOnServer()) {
            return;
        }
        Map properties = new HashMap();
        properties.putAll(JUnitTestCaseHelper.getDatabaseProperties());
        properties.put(EntityManagerProperties.PERSISTENCE_CONTEXT_COMMIT_WITHOUT_PERSIST_RULES, "true");

        EntityManager em = createEntityManager(properties);
        beginTransaction(em);
        Employee employee = new Employee();
        employee.setLastName("SomeName");
        Address addr = new Address();
        addr.setCity("Douglas");
        try {
            em.persist(employee);
            commitTransaction(em);
            verifyObjectInCacheAndDatabase(employee);
            closeEntityManager(em);

            em = createEntityManager(properties);
            beginTransaction(em);
            employee = em.find(Employee.class, employee.getId());
            employee.setAddress(addr);
            addr.getEmployees().add(employee);
            commitTransaction(em);
            verifyObjectInCacheAndDatabase(employee);
            closeEntityManager(em);

            em = createEntityManager(properties);
            clearCache();
            beginTransaction(em);
            employee = em.find(Employee.class, employee.getId());
            employee.getAddress().setCountry("country");
            employee.getAddress().getEmployees().size();
            employee.setAddress((Address)null);
            em.remove(employee);
            commitTransaction(em);

            em = createEntityManager(properties);
            beginTransaction(em);
            employee = em.find(Employee.class, employee.getId());
            assertNull("Employee Not Deleted", employee);
            commitTransaction(em);
            closeEntityManager(em);
        } catch (RuntimeException exception) {
            if (isTransactionActive(em)) {
                rollbackTransaction(em);
            }
            closeEntityManager(em);
            throw exception;
        } finally {
            try {
                em = createEntityManager();
                clearCache();
                beginTransaction(em);
                em.remove(em.find(Address.class, addr.getID()));
                commitTransaction(em);
            } catch (RuntimeException ex) {
                // ignore

            }
        }
    }

    // Test Not using the persist operation on commit.
    public void testNoPersistOnFlushProperties() {
        // Properties only works in jse.
        if (isOnServer()) {
            return;
        }
        Map properties = new HashMap();
        properties.putAll(JUnitTestCaseHelper.getDatabaseProperties());
        properties.put(EntityManagerProperties.PERSISTENCE_CONTEXT_COMMIT_WITHOUT_PERSIST_RULES, "true");

        EntityManager em = createEntityManager(properties);
        beginTransaction(em);
        Employee employee = new Employee();
        employee.setLastName("SomeName");
        Address addr = new Address();
        addr.setCity("Douglas");
        try {
            em.persist(employee);
            em.flush();
            commitTransaction(em);
            verifyObjectInCacheAndDatabase(employee);
            closeEntityManager(em);

            em = createEntityManager(properties);
            beginTransaction(em);
            employee = em.find(Employee.class, employee.getId());
            employee.setAddress(addr);
            addr.getEmployees().add(employee);
            em.flush();
            commitTransaction(em);
            verifyObjectInCacheAndDatabase(employee);
            closeEntityManager(em);

            em = createEntityManager(properties);
            clearCache();
            beginTransaction(em);
            employee = em.find(Employee.class, employee.getId());
            employee.getAddress().setCountry("country");
            employee.getAddress().getEmployees().size();
            employee.setAddress((Address)null);
            em.remove(employee);
            commitTransaction(em);

            em = createEntityManager(properties);
            beginTransaction(em);
            employee = em.find(Employee.class, employee.getId());
            assertNull("Employee Not Deleted", employee);
            commitTransaction(em);
            closeEntityManager(em);
        } catch (RuntimeException exception) {
            if (isTransactionActive(em)) {
                rollbackTransaction(em);
            }
            closeEntityManager(em);
            throw exception;
        } finally {
            try {
                em = createEntityManager();
                clearCache();
                beginTransaction(em);
                em.remove(em.find(Address.class, addr.getID()));
                commitTransaction(em);
            } catch (RuntimeException ex) {
                // ignore

            }
        }
    }

    // Test using PERSISTENCE_CONTEXT_FLUSH_MODE option.
    public void testFlushMode() {
        // Properties only works in jse.
        if (isOnServer()) {
            return;
        }
        Map properties = new HashMap();
        properties.put(PersistenceUnitProperties.PERSISTENCE_CONTEXT_FLUSH_MODE, "COMMIT");
        EntityManager em = createEntityManager(properties);
        beginTransaction(em);
        try {
            Employee emp = new Employee();
            emp.setFirstName("testFlushMode");
            emp.setLastName("McRae");
            em.persist(emp);
            Query query = em.createQuery("Select e from Employee e where e.firstName = 'testFlushMode'");
            if (query.getResultList().size() > 0) {
                fail("Query triggered flush.");
            }
            rollbackTransaction(em);
            closeEntityManager(em);
        } catch (RuntimeException exception) {
            if (isTransactionActive(em)){
                rollbackTransaction(em);
            }
            closeEntityManager(em);
            throw exception;
        }
    }

    public void testClearWithFlush(){
        EntityManager em = createEntityManager();
        beginTransaction(em);
        try{
            Employee emp = new Employee();
            emp.setFirstName("Douglas");
            emp.setLastName("McRae");
            em.persist(emp);
            commitTransaction(em);
        }catch (RuntimeException ex){
            if (isTransactionActive(em)){
                rollbackTransaction(em);
            }
            closeEntityManager(em);
            throw ex;
        }
        clearCache();
        EntityManager localEm = createEntityManager();
        beginTransaction(localEm);
        Employee emp = null;
        String originalName = "";
        boolean cleared, updated, reset = false;
        try{
            Query query = localEm.createQuery("Select e FROM Employee e where e.firstName is not null");
            emp = (Employee)query.getResultList().get(0);
            originalName = emp.getFirstName();
            emp.setFirstName("Bobster");
            localEm.flush();
            localEm.clear();
            //this test is testing the cache not the database
            commitTransaction(localEm);
            cleared = !localEm.contains(emp);
            emp = localEm.find(Employee.class, emp.getId());
            updated = emp.getFirstName().equals("Bobster");
            closeEntityManager(localEm);
        } catch (RuntimeException exception) {
            if (isTransactionActive(localEm)) {
                rollbackTransaction(localEm);
            }
            closeEntityManager(localEm);
            throw exception;
        } finally {
            //now clean up
            localEm = createEntityManager();
            beginTransaction(localEm);
            emp = localEm.find(Employee.class, emp.getId());
            emp.setFirstName(originalName);
            commitTransaction(localEm);
            emp = localEm.find(Employee.class, emp.getId());
            reset = emp.getFirstName().equals(originalName);
            closeEntityManager(localEm);
        }
        assertTrue("EntityManager not properly cleared", cleared);
        assertTrue("flushed data not merged", updated);
        assertTrue("unable to reset", reset);
    }
    // gf3596: transactions never release memory until commit, so JVM eventually crashes
    // The test verifies that there's no stale data read after transaction.
    // Because there were no TopLinkProperties.FLUSH_CLEAR_CACHE property passed
    // while creating either EM or EMF the tested behavior corresponds to
    // the default property value FlushClearCache.DropInvalidate.
    // Note that the same test would pass with FlushClearCache.Merge
    // (in that case all changes are merges into the shared cache after transaction committed),
    // but the test would fail with FlushClearCache.Drop - that mode just drops em cache
    // without doing any invalidation of the shared cache.
    public void testClearWithFlush2() {
        String firstName = "testClearWithFlush2";

        // setup
        // create employee and manager - and then remove them from the shared cache
        EntityManager em = createEntityManager();
        int employee_1_NotInCache_id = 0;
        int employee_2_NotInCache_id = 0;
        int manager_NotInCache_id = 0;
        beginTransaction(em);
        try {
            Employee employee_1_NotInCache = new Employee();
            employee_1_NotInCache.setFirstName(firstName);
            employee_1_NotInCache.setLastName("Employee_1_NotInCache");

            Employee employee_2_NotInCache = new Employee();
            employee_2_NotInCache.setFirstName(firstName);
            employee_2_NotInCache.setLastName("Employee_2_NotInCache");

            Employee manager_NotInCache = new Employee();
            manager_NotInCache.setFirstName(firstName);
            manager_NotInCache.setLastName("Manager_NotInCache");
            // employee_1 is manager, employee_2 is not
            manager_NotInCache.addManagedEmployee(employee_1_NotInCache);

            // persist
            em.persist(manager_NotInCache);
            em.persist(employee_1_NotInCache);
            em.persist(employee_2_NotInCache);
            commitTransaction(em);

            employee_1_NotInCache_id = employee_1_NotInCache.getId();
            employee_2_NotInCache_id = employee_2_NotInCache.getId();
            manager_NotInCache_id = manager_NotInCache.getId();
        } catch (RuntimeException ex){
            if (isTransactionActive(em)){
                rollbackTransaction(em);
            }
            closeEntityManager(em);
            throw ex;
        }
        // remove both manager_NotInCache and employee_NotInCache from the shared cache
        clearCache();

        // setup
        // create employee and manager - and keep them in the shared cache
        em = createEntityManager();
        int employee_1_InCache_id = 0;
        int employee_2_InCache_id = 0;
        int manager_InCache_id = 0;
        beginTransaction(em);
        try {
            Employee employee_1_InCache = new Employee();
            employee_1_InCache.setFirstName(firstName);
            employee_1_InCache.setLastName("Employee_1_InCache");

            Employee employee_2_InCache = new Employee();
            employee_2_InCache.setFirstName(firstName);
            employee_2_InCache.setLastName("Employee_2_InCache");

            Employee manager_InCache = new Employee();
            manager_InCache.setFirstName(firstName);
            manager_InCache.setLastName("Manager_InCache");
            // employee_1 is manager, employee_2 is not
            manager_InCache.addManagedEmployee(employee_1_InCache);

            // persist
            em.persist(manager_InCache);
            em.persist(employee_1_InCache);
            em.persist(employee_2_InCache);
            commitTransaction(em);

            employee_1_InCache_id = employee_1_InCache.getId();
            employee_2_InCache_id = employee_2_InCache.getId();
            manager_InCache_id = manager_InCache.getId();
        } catch (RuntimeException ex){
            if (isTransactionActive(em)){
                rollbackTransaction(em);
            }
            closeEntityManager(em);
            throw ex;
        }

        // test
        // create new employee and manager, change existing ones, flush, clear
        em = createEntityManager();
        int employee_1_New_id = 0;
        int employee_2_New_id = 0;
        int employee_3_New_id = 0;
        int employee_4_New_id = 0;
        int manager_New_id = 0;
        beginTransaction(em);
        try {
            Employee employee_1_New = new Employee();
            employee_1_New.setFirstName(firstName);
            employee_1_New.setLastName("Employee_1_New");
            em.persist(employee_1_New);
            employee_1_New_id = employee_1_New.getId();

            Employee employee_2_New = new Employee();
            employee_2_New.setFirstName(firstName);
            employee_2_New.setLastName("Employee_2_New");
            em.persist(employee_2_New);
            employee_2_New_id = employee_2_New.getId();

            Employee employee_3_New = new Employee();
            employee_3_New.setFirstName(firstName);
            employee_3_New.setLastName("Employee_3_New");
            em.persist(employee_3_New);
            employee_3_New_id = employee_3_New.getId();

            Employee employee_4_New = new Employee();
            employee_4_New.setFirstName(firstName);
            employee_4_New.setLastName("Employee_4_New");
            em.persist(employee_4_New);
            employee_4_New_id = employee_4_New.getId();

            Employee manager_New = new Employee();
            manager_New.setFirstName(firstName);
            manager_New.setLastName("Manager_New");
            em.persist(manager_New);
            manager_New_id = manager_New.getId();

            // find and update all objects created during setup
            Employee employee_1_NotInCache = em.find(Employee.class, employee_1_NotInCache_id);
            employee_1_NotInCache.setLastName(employee_1_NotInCache.getLastName() + "_Updated");
            Employee employee_2_NotInCache = em.find(Employee.class, employee_2_NotInCache_id);
            employee_2_NotInCache.setLastName(employee_2_NotInCache.getLastName() + "_Updated");
            Employee manager_NotInCache = em.find(Employee.class, manager_NotInCache_id);
            manager_NotInCache.setLastName(manager_NotInCache.getLastName() + "_Updated");

            Employee employee_1_InCache = em.find(Employee.class, employee_1_InCache_id);
            employee_1_InCache.setLastName(employee_1_InCache.getLastName() + "_Updated");
            Employee employee_2_InCache = em.find(Employee.class, employee_2_InCache_id);
            employee_2_InCache.setLastName(employee_2_InCache.getLastName() + "_Updated");
            Employee manager_InCache = em.find(Employee.class, manager_InCache_id);
            manager_InCache.setLastName(manager_InCache.getLastName() + "_Updated");

            manager_NotInCache.addManagedEmployee(employee_1_New);
            manager_InCache.addManagedEmployee(employee_2_New);

            manager_New.addManagedEmployee(employee_3_New);
            manager_New.addManagedEmployee(employee_2_NotInCache);
            manager_New.addManagedEmployee(employee_2_InCache);

            // flush
            em.flush();

            // clear and commit
            em.clear();
            commitTransaction(em);
        } catch (RuntimeException ex){
            if (isTransactionActive(em)){
                rollbackTransaction(em);
            }
            closeEntityManager(em);
            throw ex;
        }

        // verify
        String errorMsg = "";
        em = createEntityManager();

        // find and verify all objects created during setup and test

        Employee manager_NotInCache = em.find(Employee.class, manager_NotInCache_id);
        if(!manager_NotInCache.getLastName().endsWith("_Updated")) {
            errorMsg = errorMsg + "manager_NotInCache lastName NOT updated; ";
        }
        Iterator it = manager_NotInCache.getManagedEmployees().iterator();
        while(it.hasNext()) {
            Employee emp = (Employee)it.next();
            if(emp.getId() == employee_1_NotInCache_id) {
                if(!emp.getLastName().endsWith("_Updated")) {
                    errorMsg = errorMsg + "employee_1_NotInCache lastName NOT updated; ";
                }
            } else if(emp.getId() == employee_1_New_id) {
                if(!emp.getLastName().endsWith("_New")) {
                    errorMsg = errorMsg + "employee_1_New lastName wrong; ";
                }
            } else {
                errorMsg = errorMsg + "manager_NotInCache has unexpected employee: lastName = " + emp.getLastName();
            }
        }
        if(manager_NotInCache.getManagedEmployees().size() != 2) {
            errorMsg = errorMsg + "manager_NotInCache.getManagedEmployees().size() != 2; size = " + manager_NotInCache.getManagedEmployees().size();
        }

        Employee manager_InCache = em.find(Employee.class, manager_InCache_id);
        if(!manager_InCache.getLastName().endsWith("_Updated")) {
            errorMsg = errorMsg + "manager_InCache lastName NOT updated; ";
        }
        it = manager_InCache.getManagedEmployees().iterator();
        while(it.hasNext()) {
            Employee emp = (Employee)it.next();
            if(emp.getId() == employee_1_InCache_id) {
                if(!emp.getLastName().endsWith("_Updated")) {
                    errorMsg = errorMsg + "employee_1_InCache lastName NOT updated; ";
                }
            } else if(emp.getId() == employee_2_New_id) {
                if(!emp.getLastName().endsWith("_New")) {
                    errorMsg = errorMsg + "employee_2_New lastName wrong; ";
                }
            } else {
                errorMsg = errorMsg + "manager_InCache has unexpected employee: lastName = " + emp.getLastName();
            }
        }
        if(manager_InCache.getManagedEmployees().size() != 2) {
            errorMsg = errorMsg + "manager_InCache.getManagedEmployees().size() != 2; size = " + manager_InCache.getManagedEmployees().size();
        }

        Employee manager_New = em.find(Employee.class, manager_New_id);
        if(!manager_New.getLastName().endsWith("_New")) {
            errorMsg = errorMsg + "manager_New lastName wrong; ";
        }
        it = manager_New.getManagedEmployees().iterator();
        while(it.hasNext()) {
            Employee emp = (Employee)it.next();
            if(emp.getId() == employee_2_NotInCache_id) {
                if(!emp.getLastName().endsWith("_Updated")) {
                    errorMsg = errorMsg + "employee_2_NotInCache_id lastName NOT updated; ";
                }
            } else if(emp.getId() == employee_2_InCache_id) {
                if(!emp.getLastName().endsWith("_Updated")) {
                    errorMsg = errorMsg + "employee_2_InCache_id lastName NOT updated; ";
                }
            } else if(emp.getId() == employee_3_New_id) {
                if(!emp.getLastName().endsWith("_New")) {
                    errorMsg = errorMsg + "employee_3_New lastName wrong; ";
                }
            } else {
                errorMsg = errorMsg + "manager_New has unexpected employee: lastName = " + emp.getLastName();
            }
        }
        if(manager_New.getManagedEmployees().size() != 3) {
            errorMsg = errorMsg + "manager_InCache.getManagedEmployees().size() != 3; size = " + manager_InCache.getManagedEmployees().size();
        }
        Employee employee_4_New = em.find(Employee.class, employee_4_New_id);
        if(!employee_4_New.getLastName().endsWith("_New")) {
            errorMsg = errorMsg + "employee_4_New lastName wrong; ";
        }
        closeEntityManager(em);

        // clean up
        // remove all objects created during this test and clear the cache.
        em = createEntityManager();
        try {
            beginTransaction(em);
            List<Employee> list = em.createQuery("Select e from Employee e where e.firstName = '"+firstName+"'").getResultList();
            Iterator<Employee> i = list.iterator();
            while (i.hasNext()){
                Employee e = i.next();
                if (e.getManager() != null){
                    e.getManager().removeManagedEmployee(e);
                    e.setManager(null);
                }
                em.remove(e);
            }
            commitTransaction(em);
        } catch (RuntimeException ex){
            if (isTransactionActive(em)){
                rollbackTransaction(em);
            }
            // ignore exception in clean up in case there's an error in test
            if(errorMsg.length() == 0) {
                throw ex;
            }
        }
        clearCache();

        if(errorMsg.length() > 0) {
            fail(errorMsg);
        }
    }

    /* ToDo: move these to a memory test suite.
    // gf3596: transactions never release memory until commit, so JVM eventually crashes.
    // Attempts to compare memory consumption between the two FlushClearCache modes.
    // If the values changed to be big enough (in TopLink I tried nFlashes = 30 , nInsertsPerFlush = 10000)
    // internalMassInsertFlushClear(FlushClearCache.Merge, 30, 10000) will run out of memory,
    // but internalMassInsertFlushClear(null, 30, 10000) will still be ok.
    public void testMassInsertFlushClear() {
        int nFlushes = 20;
        int nPersistsPerFlush = 50;
        long[] defaultFreeMemoryDelta = internalMassInsertFlushClear(null, nFlushes, nPersistsPerFlush);
        long[] mergeFreeMemoryDelta = internalMassInsertFlushClear(FlushClearCache.Merge, nFlushes, nPersistsPerFlush);
        // disregard the flush if any of the two FreeMemoryDeltas is negative - clearly that's gc artefact.
        int nEligibleFlushes = 0;
        long diff = 0;
        for(int nFlush = 0; nFlush < nFlushes; nFlush++) {
            if(defaultFreeMemoryDelta[nFlush] >= 0 && mergeFreeMemoryDelta[nFlush] >= 0) {
                nEligibleFlushes++;
                diff = diff + mergeFreeMemoryDelta[nFlush] - defaultFreeMemoryDelta[nFlush];
            }
        }
        long lowEstimateOfBytesPerObject = 200;
        long diffPerObject = diff / (nEligibleFlushes * nPersistsPerFlush);
        if(diffPerObject < lowEstimateOfBytesPerObject) {
            fail("difference in freememory per object persisted " + diffPerObject + " is lower than lowEstimateOfBytesPerObject " + lowEstimateOfBytesPerObject);
        }
    }

    // memory usage with different FlushClearCache modes.
    protected long[] internalMassInsertFlushClear(String propValue, int nFlushes, int nPersistsPerFlush) {
        // set logDebug to true to output the freeMemory values after each flush/clear
        boolean logDebug = false;
        String firstName = "testMassInsertFlushClear";
        EntityManager em;
        if(propValue == null) {
            // default value FlushClearCache.DropInvalidate will be used
            em = createEntityManager();
            if(logDebug) {
                System.out.println(FlushClearCache.DEFAULT);
            }
        } else {
            HashMap map = new HashMap(1);
            map.put(PersistenceUnitProperties.FLUSH_CLEAR_CACHE, propValue);
            em = getEntityManagerFactory().createEntityManager(map);
            if(logDebug) {
                System.out.println(propValue);
            }
        }
        // For enhance accuracy of memory measuring allocate everything first:
        // make a first run and completely disregard its results - somehow
        // that get freeMemory function to report more accurate results in the second run -
        // which is the only one used to calculate results.
        if(logDebug) {
            System.out.println("The first run is ignored");
        }
        long freeMemoryOld;
        long freeMemoryNew;
        long[] freeMemoryDelta = new long[nFlushes];
        beginTransaction(em);
        try {
            // Try to force garbage collection NOW.
            System.gc();System.gc();System.gc();System.gc();System.gc();System.gc();System.gc();System.gc();
            freeMemoryOld = Runtime.getRuntime().freeMemory();
            if(logDebug) {
                System.out.println("initial freeMemory = " + freeMemoryOld);
            }
            for(int nFlush = 0; nFlush < nFlushes; nFlush++) {
                for(int nPersist = 0; nPersist < nPersistsPerFlush; nPersist++) {
                    Employee emp = new Employee();
                    emp.setFirstName(firstName);
                    int nEmployee = nFlush * nPersistsPerFlush + nPersist;
                    emp.setLastName("lastName_" + Integer.toString(nEmployee));
                    em.persist(emp);
                }
                em.flush();
                em.clear();
                // Try to force garbage collection NOW.
                System.gc();System.gc();System.gc();System.gc();System.gc();System.gc();System.gc();System.gc();
                freeMemoryNew = Runtime.getRuntime().freeMemory();
                freeMemoryDelta[nFlush] = freeMemoryOld - freeMemoryNew;
                freeMemoryOld = freeMemoryNew;
                if(logDebug) {
                    System.out.println(nFlush +": after flush/clear freeMemory = " + freeMemoryNew);
                }
            }
        } finally {
            rollbackTransaction(em);
            em = null;
        }

        if(logDebug) {
            System.out.println("The second run");
        }
        // now allocate again - with gc and memory measuring
        if(propValue == null) {
            // default value FlushClearCache.DropInvalidate will be used
            em = createEntityManager();
        } else {
            HashMap map = new HashMap(1);
            map.put(PersistenceUnitProperties.FLUSH_CLEAR_CACHE, propValue);
            em = getEntityManagerFactory().createEntityManager(map);
        }
        beginTransaction(em);
        try {
            // Try to force garbage collection NOW.
            System.gc();System.gc();System.gc();System.gc();System.gc();System.gc();System.gc();System.gc();
            freeMemoryOld = Runtime.getRuntime().freeMemory();
            if(logDebug) {
                System.out.println("initial freeMemory = " + freeMemoryOld);
            }
            for(int nFlush = 0; nFlush < nFlushes; nFlush++) {
                for(int nPersist = 0; nPersist < nPersistsPerFlush; nPersist++) {
                    Employee emp = new Employee();
                    emp.setFirstName(firstName);
                    int nEmployee = nFlush * nPersistsPerFlush + nPersist;
                    emp.setLastName("lastName_" + Integer.toString(nEmployee));
                    em.persist(emp);
                }
                em.flush();
                em.clear();
                // Try to force garbage collection NOW.
                System.gc();System.gc();System.gc();System.gc();System.gc();System.gc();System.gc();System.gc();
                freeMemoryNew = Runtime.getRuntime().freeMemory();
                freeMemoryDelta[nFlush] = freeMemoryOld - freeMemoryNew;
                freeMemoryOld = freeMemoryNew;
                if(logDebug) {
                    System.out.println(nFlush +": after flush/clear freeMemory = " + freeMemoryNew);
                }
            }
            return freeMemoryDelta;
        } finally {
            rollbackTransaction(em);
        }
    }*/

    public void testClearInTransaction(){
        EntityManager em = createEntityManager();
        beginTransaction(em);
        try{
            Employee emp = new Employee();
            emp.setFirstName("Tommy");
            emp.setLastName("Marsh");
            em.persist(emp);
            commitTransaction(em);
        }catch (RuntimeException ex){
            if (isTransactionActive(em)){
                rollbackTransaction(em);
            }
            closeEntityManager(em);
            throw ex;
        }
        clearCache();
        em = createEntityManager();
        beginTransaction(em);
        Employee emp = null;
        String originalName = "";
        try {
            Query query = em.createQuery("Select e FROM Employee e where e.firstName is not null");
            emp = (Employee)query.getResultList().get(0);
            originalName = emp.getFirstName();
            emp.setFirstName("Bobster");
            em.clear();
            commitTransaction(em);
        } catch (RuntimeException ex) {
            if (isTransactionActive(em)) {
                rollbackTransaction(em);
            }
            closeEntityManager(em);
            throw ex;
        }
        boolean cleared = !em.contains(emp);
        emp = em.find(Employee.class, emp.getId());
        closeEntityManager(em);
        assertTrue("EntityManager not properly cleared", cleared);
        assertTrue("Employee was updated although EM was cleared", emp.getFirstName().equals(originalName));
    }

    public void testExtendedPersistenceContext() {
        // Extended persistence context are not supported in the server.
        // TODO: make this test use an extended entity manager in the server by creating from the factory and joining transaction.
        if (isOnServer()) {
            return;
        }

        String firstName = "testExtendedPersistenceContext";
        int originalSalary = 0;

        Employee empNew = new Employee();
        empNew.setFirstName(firstName);
        empNew.setLastName("new");
        empNew.setSalary(originalSalary);

        Employee empToBeRemoved = new Employee();
        empToBeRemoved.setFirstName(firstName);
        empToBeRemoved.setLastName("toBeRemoved");
        empToBeRemoved.setSalary(originalSalary);

        Employee empToBeRefreshed = new Employee();
        empToBeRefreshed.setFirstName(firstName);
        empToBeRefreshed.setLastName("toBeRefreshed");
        empToBeRefreshed.setSalary(originalSalary);

        Employee empToBeMerged = new Employee();
        empToBeMerged.setFirstName(firstName);
        empToBeMerged.setLastName("toBeMerged");
        empToBeMerged.setSalary(originalSalary);

        // setup: make sure no Employee with the specified firstName exists and create the existing employees.
        EntityManager em = createEntityManager();
        beginTransaction(em);
        try{
            Query q = em.createQuery("SELECT e FROM Employee e WHERE e.firstName = '"+firstName+"'");
            for (Object oldData : q.getResultList()) {
                em.remove(oldData);
            }
            commitTransaction(em);
            beginTransaction(em);
            em.persist(empToBeRemoved);
            em.persist(empToBeRefreshed);
            em.persist(empToBeMerged);
            commitTransaction(em);
        }catch (RuntimeException ex){
            if (isTransactionActive(em)){
                rollbackTransaction(em);
            }
            closeEntityManager(em);
            throw ex;
        }
        closeEntityManager(em);
        clearCache();

        // create entityManager with extended Persistence Context.
        em = createEntityManager();

        try {
            // first test
            // without starting transaction persist, remove, refresh, merge

            em.persist(empNew);

            Employee empToBeRemovedExtended = em.find(Employee.class, empToBeRemoved.getId());
            em.remove(empToBeRemovedExtended);

            Employee empToBeRefreshedExtended = em.find(Employee.class, empToBeRefreshed.getId());
            int newSalary = 100;
            // Use another EntityManager to alter empToBeRefreshed in the db
            beginTransaction(em);
            empToBeRefreshed = em.find(Employee.class, empToBeRefreshed.getId());
            empToBeRefreshed.setSalary(newSalary);
            commitTransaction(em);
            // now refesh
            em.refresh(empToBeRefreshedExtended);

            Employee empToBeMergedExtended = em.find(Employee.class, empToBeMerged.getId());
            // alter empToBeRefreshed
            empToBeMerged.setSalary(newSalary);
            // now merge
            em.merge(empToBeMerged);

            // begin and commit transaction
            beginTransaction(em);
            commitTransaction(em);

            // verify objects are correct in the PersistenceContext after transaction
            if(!em.contains(empNew)) {
                fail("empNew gone from extended PersistenceContext after transaction committed");
            }
            if(em.contains(empToBeRemovedExtended)) {
                fail("empToBeRemovedExtended still in extended PersistenceContext after transaction committed");
            }
            if(!em.contains(empToBeRefreshedExtended)) {
                fail("empToBeRefreshedExtended gone from extended PersistenceContext after transaction committed");
            } else if(empToBeRefreshedExtended.getSalary() != newSalary) {
                fail("empToBeRefreshedExtended still has the original salary after transaction committed");
            }
            if(!em.contains(empToBeMergedExtended)) {
                fail("empToBeMergedExtended gone from extended PersistenceContext after transaction committed");
            } else if(empToBeMergedExtended.getSalary() != newSalary) {
                fail("empToBeMergedExtended still has the original salary after transaction committed");
            }

            // verify objects are correct in the db after transaction
            clearCache();
            Employee empNewFound = em.find(Employee.class, empNew.getId());
            if(empNewFound == null) {
                fail("empNew not in the db after transaction committed");
            }
            Employee empToBeRemovedFound = em.find(Employee.class, empToBeRemoved.getId());
            if(empToBeRemovedFound != null) {
                fail("empToBeRemoved is still in the db after transaction committed");
            }
            Employee empToBeRefreshedFound = em.find(Employee.class, empToBeRefreshed.getId());
            if(empToBeRefreshedFound == null) {
                fail("empToBeRefreshed not in the db after transaction committed");
            } else if(empToBeRefreshedFound.getSalary() != newSalary) {
                fail("empToBeRefreshed still has the original salary in the db after transaction committed");
            }
            Employee empToBeMergedFound = em.find(Employee.class, empToBeMerged.getId());
            if(empToBeMergedFound == null) {
                fail("empToBeMerged not in the db after transaction committed");
            } else if(empToBeMergedFound.getSalary() != newSalary) {
                fail("empToBeMerged still has the original salary in the db after transaction committed");
            }

            // second test
            // without starting transaction persist, remove, refresh, merge for the second time:
            // now return to the original state of the objects:
            // remove empNew, persist empToBeRemoved, set empToBeRefreshed and empToBeMerged the original salary.

            em.persist(empToBeRemoved);
            em.remove(empNew);

            // Use another EntityManager to alter empToBeRefreshed in the db
            beginTransaction(em);
            empToBeRefreshed = em.find(Employee.class, empToBeRefreshed.getId());
            empToBeRefreshed.setSalary(originalSalary);
            commitTransaction(em);
            // now refesh
            em.refresh(empToBeRefreshedExtended);

            // alter empToBeRefreshedFound - can't use empToBeRefreshed here because of its older version().
            empToBeMergedFound.setSalary(originalSalary);
            // now merge
            em.merge(empToBeMergedFound);

            // begin and commit the second transaction
            beginTransaction(em);
            commitTransaction(em);

            // verify objects are correct in the PersistenceContext
            if(em.contains(empNew)) {
                fail("empNew not gone from extended PersistenceContext after the second transaction committed");
            }
            if(!em.contains(empToBeRemoved)) {
                fail("empToBeRemoved is not in extended PersistenceContext after the second transaction committed");
            }
            if(!em.contains(empToBeRefreshedExtended)) {
                fail("empToBeRefreshedExtended gone from extended PersistenceContext after the second transaction committed");
            } else if(empToBeRefreshedExtended.getSalary() != originalSalary) {
                fail("empToBeRefreshedExtended still doesn't have the original salary after the second transaction committed");
            }
            if(!em.contains(empToBeMergedExtended)) {
                fail("empToBeMergedExtended gone from extended PersistenceContext after the second transaction committed");
            } else if(empToBeMergedExtended.getSalary() != originalSalary) {
                fail("empToBeMergedExtended doesn't have the original salary after the second transaction committed");
            }

            // verify objects are correct in the db
            clearCache();
            Employee empNewFound2 = em.find(Employee.class, empNew.getId());
            if(empNewFound2 != null) {
                fail("empNew still in the db after the second transaction committed");
            }
            Employee empToBeRemovedFound2 = em.find(Employee.class, empToBeRemoved.getId());
            if(empToBeRemovedFound2 == null) {
                fail("empToBeRemoved is not in the db after the second transaction committed");
            }
            Employee empToBeRefreshedFound2 = em.find(Employee.class, empToBeRefreshed.getId());
            if(empToBeRefreshedFound2 == null) {
                fail("empToBeRefreshed not in the db after the second transaction committed");
            } else if(empToBeRefreshedFound2.getSalary() != originalSalary) {
                fail("empToBeRefreshed doesn't have the original salary in the db after the second transaction committed");
            }
            Employee empToBeMergedFound2 = em.find(Employee.class, empToBeMerged.getId());
            if(empToBeMergedFound2 == null) {
                fail("empToBeMerged not in the db after the second transaction committed");
            } else if(empToBeMergedFound2.getSalary() != originalSalary) {
                fail("empToBeMerged doesn't have the original salary in the db after the second transaction committed");
            }

            // third test
            // without starting transaction persist, remove, refresh, merge
            // The same as the first test - but now we'll rollback.
            // The objects should be detached.

            beginTransaction(em);
            em.persist(empNew);
            em.remove(empToBeRemoved);

            // Use another EntityManager to alter empToBeRefreshed in the db
            EntityManager em2 = createEntityManager();
            em2.getTransaction().begin();
            try{
                empToBeRefreshed = em2.find(Employee.class, empToBeRefreshed.getId());
                empToBeRefreshed.setSalary(newSalary);
                em2.getTransaction().commit();
            }catch (RuntimeException ex){
                if (em2.getTransaction().isActive()){
                    em2.getTransaction().rollback();
                }
                throw ex;
            }finally{
                em2.close();
            }
            // now refesh
            em.refresh(empToBeRefreshedExtended);

            // alter empToBeRefreshed
            empToBeMergedFound2.setSalary(newSalary);
            // now merge
            em.merge(empToBeMergedFound2);

            // flush and ROLLBACK the third transaction
            em.flush();
            rollbackTransaction(em);

            // verify objects are correct in the PersistenceContext after the third transaction rolled back
            if(em.contains(empNew)) {
                fail("empNew is still in extended PersistenceContext after the third transaction rolled back");
            }
            if(em.contains(empToBeRemoved)) {
                fail("empToBeRemoved is still in extended PersistenceContext after the third transaction rolled back");
            }
            if(em.contains(empToBeRefreshedExtended)) {
                fail("empToBeRefreshedExtended is still in extended PersistenceContext after the third transaction rolled back");
            } else if(empToBeRefreshedExtended.getSalary() != newSalary) {
                fail("empToBeRefreshedExtended still has the original salary after third transaction rolled back");
            }
            if(em.contains(empToBeMergedExtended)) {
                fail("empToBeMergedExtended is still in extended PersistenceContext after the third transaction rolled back");
            } else if(empToBeMergedExtended.getSalary() != newSalary) {
                fail("empToBeMergedExtended still has the original salary after third transaction rolled back");
            }

            // verify objects are correct in the db after the third transaction rolled back
            clearCache();
            Employee empNewFound3 = em.find(Employee.class, empNew.getId());
            if(empNewFound3 != null) {
                fail("empNew is in the db after the third transaction rolled back");
            }
            Employee empToBeRemovedFound3 = em.find(Employee.class, empToBeRemoved.getId());
            if(empToBeRemovedFound3 == null) {
                fail("empToBeRemoved not in the db after the third transaction rolled back");
            }
            Employee empToBeRefreshedFound3 = em.find(Employee.class, empToBeRefreshed.getId());
            if(empToBeRefreshedFound3 == null) {
                fail("empToBeRefreshed not in the db after the third transaction rolled back");
            } else if(empToBeRefreshedFound3.getSalary() != newSalary) {
                fail("empToBeRefreshed has the original salary in the db after the third transaction rolled back");
            }
            Employee empToBeMergedFound3 = em.find(Employee.class, empToBeMerged.getId());
            if(empToBeMergedFound3 == null) {
                fail("empToBeMerged not in the db after the third transaction rolled back");
            } else if(empToBeMergedFound3.getSalary() != originalSalary) {
                fail("empToBeMerged still doesn't have the original salary in the db after the third transaction rolled back");
            }
        }catch (RuntimeException ex){
            if (isTransactionActive(em)){
                rollbackTransaction(em);
            }
            throw ex;
        } finally {
            closeEntityManager(em);
        }
    }

    public void testReadOnlyTransactionalData(){
        if (isOnServer() || getPlatform().isH2() || getPlatform().isDerby() || getPlatform().isSymfoware() || getPlatform().isSQLServer()) {
            //H2, Derby, Symfoware and SQL Server will get lock timeouts because the transaction is holding a lock on the table for a change.  Test can not be run against these databases.
            return;
        }
        EntityManager em = createEntityManager();
        em.getTransaction().begin();
        Employee emp = new Employee("Bob", String.valueOf(System.currentTimeMillis()));
        em.persist(emp);
        em.flush();
        try{
            Employee result = (Employee) em.createQuery("Select e from Employee e where e.lastName = :lName").setHint(QueryHints.READ_ONLY, true).setParameter("lName", emp.getLastName()).getSingleResult();
        }catch (NoResultException ex){
            // this exception should be thrown because the read only query should not read txnal data
        }
        em.getTransaction().rollback();
        em.clear();
        assertNull("Uncommitted Data loaded into cache", em.find(Employee.class, emp.getId()));
    }
    
    public void testReadOnlyCachedLazyAssociation() {
        EntityManager em = createEntityManager();
        Integer empId = null;
        Employee emp = null;

        try {
            // setup
            try {
                beginTransaction(em);
                emp = new Employee();
                emp.setFirstName("Mark");
                emp.setLastName("Dowder");
                final PhoneNumber phone = new PhoneNumber("work", "613", "5555555");
                emp.addPhoneNumber(phone);
                final PhoneNumber newPhone = new PhoneNumber("home", "613", "4444444");
                emp.addPhoneNumber(newPhone);
                final Address address = new Address("SomeStreet", "somecity", "province", "country", "postalcode");
                emp.setAddress(address);
                em.persist(emp);
                em.flush();
                commitTransaction(em);

                empId = emp.getId();

                // clear cache
                em.getEntityManagerFactory().getCache().evictAll();
                getServerSession().getIdentityMapAccessor().initializeIdentityMaps();
            } catch (RuntimeException ex) {
                if (isTransactionActive(em)) {
                    rollbackTransaction(em);
                }
                closeEntityManager(em);
                throw ex;
            }

            final Employee employee = em.find(Employee.class, empId);
            Assert.assertNotNull("No Employee retrieved", employee);
            // Trigger Bug#474232
            employee.getAddress();

            final Employee cachedEmployee = em.createNamedQuery("findEmployeeByPK", Employee.class).
                    setParameter("id", empId).
                    setHint(QueryHints.READ_ONLY, HintValues.TRUE).
                    getSingleResult();
            Assert.assertNotNull("Employee not found", cachedEmployee);
            final Address address = cachedEmployee.getAddress();
            Assert.assertNotNull("Address of employee not retrieved", address);
        } finally {
            // Clean up
            if (empId != null) {
                beginTransaction(em);
                em.remove(em.merge(emp));
                commitTransaction(em);
            }
            closeEntityManager(em);
        }
    }

    public void testReadOnlyCachedLazyAssociationInNestedEmbeddable() {
        EntityManager em = createEntityManager();
        Integer empId = null;
        Employee emp = null;

        try {
            // setup
            try {
                beginTransaction(em);
                emp = new Employee();
                emp.setFirstName("Mike");
                emp.setLastName("Dowder");
                final Address address = new Address("Street", "City", "Province", "Country", "PostalCode");
                final EmploymentPeriod employmentPeriod = new EmploymentPeriod(new Date(System.currentTimeMillis()), new Date(System.currentTimeMillis()));
                final FormerEmployment formerEmployment = new FormerEmployment("Former company", employmentPeriod);
                employmentPeriod.setCompanyAddress(address);
                emp.setFormerEmployment(formerEmployment);
                em.persist(emp);
                em.flush();
                commitTransaction(em);

                empId = emp.getId();

                // clear cache
                em.getEntityManagerFactory().getCache().evictAll();
                getServerSession().getIdentityMapAccessor().initializeIdentityMaps();
            } catch (RuntimeException ex) {
                if (isTransactionActive(em)) {
                    rollbackTransaction(em);
                }
                throw ex;
            }

            final Employee employee = em.find(Employee.class, empId);
            Assert.assertNotNull("No Employee retrieved", employee);
            // Trigger Bug#474232
            employee.getFormerEmployment().getPeriod().getCompanyAddress();

            final Employee cachedEmployee = em.createNamedQuery("findEmployeeByPK", Employee.class).
                    setParameter("id", empId).
                    setHint(QueryHints.READ_ONLY, HintValues.TRUE).
                    getSingleResult();
            Assert.assertNotNull("Employee not found", cachedEmployee);
            final FormerEmployment formerEmployment = employee.getFormerEmployment();
            Assert.assertNotNull("Former employment details not retrieved", formerEmployment);
            final EmploymentPeriod employmentPeriod = formerEmployment.getPeriod();
            Assert.assertNotNull("Former employment period not retrieved", employmentPeriod);
            final Address address = employmentPeriod.getCompanyAddress();
            Assert.assertNotNull("Former employment address not retrieved", address);
        } finally {
            // Clean up
            if (empId != null) {
                beginTransaction(em);
                em.remove(em.merge(emp));
                commitTransaction(em);
            }
            closeEntityManager(em);
        }
    }

    public void testReadTransactionIsolation_CustomUpdate() {
        internalTestReadTransactionIsolation(false, false, false, false);
    }
    public void testReadTransactionIsolation_CustomUpdate_Flush() {
        internalTestReadTransactionIsolation(false, false, false, true);
    }
    public void testReadTransactionIsolation_CustomUpdate_Refresh() {
        internalTestReadTransactionIsolation(false, false, true, false);
    }
    public void testReadTransactionIsolation_CustomUpdate_Refresh_Flush() {
        internalTestReadTransactionIsolation(false, false, true, true);
    }
    public void testReadTransactionIsolation_UpdateAll() {
        internalTestReadTransactionIsolation(false, true, false, false);
    }
    public void testReadTransactionIsolation_UpdateAll_Flush() {
        internalTestReadTransactionIsolation(false, true, false, true);
    }
    public void testReadTransactionIsolation_UpdateAll_Refresh() {
        internalTestReadTransactionIsolation(false, true, true, false);
    }
    public void testReadTransactionIsolation_UpdateAll_Refresh_Flush() {
        internalTestReadTransactionIsolation(false, true, true, true);
    }
    public void testReadTransactionIsolation_OriginalInCache_CustomUpdate() {
        internalTestReadTransactionIsolation(true, false, false, false);
    }
    public void testReadTransactionIsolation_OriginalInCache_CustomUpdate_Flush() {
        internalTestReadTransactionIsolation(true, false, false, true);
    }
    public void testReadTransactionIsolation_OriginalInCache_CustomUpdate_Refresh() {
        internalTestReadTransactionIsolation(true, false, true, false);
    }
    public void testReadTransactionIsolation_OriginalInCache_CustomUpdate_Refresh_Flush() {
        internalTestReadTransactionIsolation(true, false, true, true);
    }
    public void testReadTransactionIsolation_OriginalInCache_UpdateAll() {
        internalTestReadTransactionIsolation(true, true, false, false);
    }
    public void testReadTransactionIsolation_OriginalInCache_UpdateAll_Flush() {
        internalTestReadTransactionIsolation(true, true, false, true);
    }
    public void testReadTransactionIsolation_OriginalInCache_UpdateAll_Refresh() {
        internalTestReadTransactionIsolation(true, true, true, false);
    }
    public void testReadTransactionIsolation_OriginalInCache_UpdateAll_Refresh_Flush() {
        internalTestReadTransactionIsolation(true, true, true, true);
    }

    protected void internalTestReadTransactionIsolation(boolean shouldOriginalBeInParentCache, boolean shouldUpdateAll, boolean shouldRefresh, boolean shouldFlush) {
        if (shouldUpdateAll && (JUnitTestCase.getServerSession()).getPlatform().isSymfoware()) {
            getServerSession().logMessage("A testReadTransactionIsolation test skipped for this platform, "
                    + "Symfoware doesn't support UpdateAll/DeleteAll on multi-table objects (see rfe 298193).");
            return;
        }

        //setup
        String firstName = "testReadTransactionIsolation";

        // make sure no Employee with the specified firstName exists.
        EntityManager em = createEntityManager();
        beginTransaction(em);
        try{
            Query q = em.createQuery("SELECT e FROM Employee e WHERE e.firstName = '"+firstName+"'");
            for (Object oldData : q.getResultList()) {
                em.remove(oldData);
            }
            commitTransaction(em);
        }catch (RuntimeException ex){
            if (isTransactionActive(em)){
                rollbackTransaction(em);
            }
            closeEntityManager(em);
            throw ex;
        }
        clearCache();
        em.clear();

        // create and persist the object
        String lastNameOriginal = "Original";
        int salaryOriginal = 0;
        Employee employee = new Employee();
        employee.setFirstName(firstName);
        employee.setLastName(lastNameOriginal);
        employee.setSalary(salaryOriginal);
        beginTransaction(em);
        try{
            em.persist(employee);
            commitTransaction(em);
        }catch (RuntimeException ex){
            if (isTransactionActive(em)){
                rollbackTransaction(em);
            }
            closeEntityManager(em);
            throw ex;
        }

        if(!shouldOriginalBeInParentCache) {
            clearCache();
        }
        em.clear();

        Employee employeeUOW = null;

        int salaryNew = 100;
        String lastNameNew = "New";

        beginTransaction(em);
        Query selectQuery = em.createQuery("SELECT OBJECT(e) FROM Employee e WHERE e.firstName = '"+firstName+"'");

        try{
            if(shouldRefresh) {
                String lastNameAlternative = "Alternative";
                int salaryAlternative = 50;
                employeeUOW = (Employee)selectQuery.getSingleResult();
                employeeUOW.setLastName(lastNameAlternative);
                employeeUOW.setSalary(salaryAlternative);
            }

            int nUpdated;
            if(shouldUpdateAll) {
                nUpdated = em.createQuery("UPDATE Employee e set e.lastName = '" + lastNameNew + "' where e.firstName like '" + firstName + "'").setFlushMode(FlushModeType.AUTO).executeUpdate();
            } else {
                nUpdated = em.createNativeQuery("UPDATE CMP3_EMPLOYEE SET L_NAME = '" + lastNameNew + "', VERSION = VERSION + 1 WHERE F_NAME LIKE '" + firstName + "'").setFlushMode(FlushModeType.AUTO).executeUpdate();
            }
            assertTrue("nUpdated=="+ nUpdated +"; 1 was expected", nUpdated == 1);

            if(shouldFlush) {
                selectQuery.setFlushMode(FlushModeType.AUTO);
            } else {
                selectQuery.setFlushMode(FlushModeType.COMMIT);
            }

            if(shouldRefresh) {
                selectQuery.setHint("eclipselink.refresh", Boolean.TRUE);
                employeeUOW = (Employee)selectQuery.getSingleResult();
                selectQuery.setHint("eclipselink.refresh", Boolean.FALSE);
            } else {
                employeeUOW = (Employee)selectQuery.getSingleResult();
            }
            assertTrue("employeeUOW.getLastName()=="+ employeeUOW.getLastName() +"; " + lastNameNew + " was expected", employeeUOW.getLastName().equals(lastNameNew));

            employeeUOW.setSalary(salaryNew);

            employeeUOW = (Employee)selectQuery.getSingleResult();
            assertTrue("employeeUOW.getSalary()=="+ employeeUOW.getSalary() +"; " + salaryNew + " was expected", employeeUOW.getSalary() == salaryNew);

            commitTransaction(em);
        }catch (Throwable ex){
            if (isTransactionActive(em)){
                rollbackTransaction(em);
            }
            closeEntityManager(em);
            if (usesSOP() && !isSOPRecoverable()) {
                int expectedExceptionCode;
                if (shouldUpdateAll) {
                    // getSingleResult is expected to fail because SOP field is set to null after bulk update
                    expectedExceptionCode = QueryException.SOP_OBJECT_IS_NOT_FOUND;
                } else {
                    // getSingleResult is expected to fail because SOP field became stale after custom sql
                    expectedExceptionCode = QueryException.SOP_OBJECT_WRONG_VERSION;
                }
                if (ex instanceof PersistenceException) {
                    if (ex.getCause() instanceof QueryException && ((QueryException)ex.getCause()).getErrorCode() == expectedExceptionCode) {
                        // getSingleResult is expected to fail.
                        return;
                    } else {
                        fail("Wrong cause of PersistenceException: " + ex.getCause());
                    }
                } else {
                    fail("PersistenceException was expected");
                }
            } else {
                if (Error.class.isAssignableFrom(ex.getClass())){
                    throw (Error)ex;
                }else{
                    throw (RuntimeException)ex;
                }
            }
        }

        Employee employeeFoundAfterTransaction = em.find(Employee.class, employeeUOW.getId());
        assertTrue("employeeFoundAfterTransaction().getLastName()=="+ employeeFoundAfterTransaction.getLastName() +"; " + lastNameNew + " was expected", employeeFoundAfterTransaction.getLastName().equals(lastNameNew));
        assertTrue("employeeFoundAfterTransaction().getSalary()=="+ employeeFoundAfterTransaction.getSalary() +"; " + salaryNew + " was expected", employeeFoundAfterTransaction.getSalary() == salaryNew);

        // The cache should be invalidated because the commit should detect a jump in the version number and invalidate the object.
        EntityManager em2 = createEntityManager();
        employeeFoundAfterTransaction = em2.find(Employee.class, employeeUOW.getId());
        assertTrue("employeeFoundAfterTransaction().getLastName()=="+ employeeFoundAfterTransaction.getLastName() +"; " + lastNameNew + " was expected", employeeFoundAfterTransaction.getLastName().equals(lastNameNew));
        assertTrue("employeeFoundAfterTransaction().getSalary()=="+ employeeFoundAfterTransaction.getSalary() +"; " + salaryNew + " was expected", employeeFoundAfterTransaction.getSalary() == salaryNew);
        closeEntityManager(em2);

        // clean up
        beginTransaction(em);
        try{
            Query q = em.createQuery("SELECT e FROM Employee e WHERE e.firstName = '"+firstName+"'");
            for (Object oldData : q.getResultList()) {
                em.remove(oldData);
            }
            commitTransaction(em);
        }catch (RuntimeException ex){
            if (isTransactionActive(em)){
                rollbackTransaction(em);
            }
            closeEntityManager(em);
            throw ex;
        }
        clearCache();
        closeEntityManager(em);
    }

    // test for bug 4755392:
    // AFTER DELETEALL OBJECT STILL DEEMED EXISTING
    public void testFindDeleteAllPersist() {
        if ((JUnitTestCase.getServerSession()).getPlatform().isSymfoware()) {
            getServerSession().logMessage("Test testFindDeleteAllPersist skipped for this platform, "
                    + "Symfoware doesn't support UpdateAll/DeleteAll on multi-table objects (see rfe 298193).");
            return;
        }
        String firstName = "testFindDeleteAllPersist";

        // create Employees
        Employee empWithAddress = new Employee();
        empWithAddress.setFirstName(firstName);
        empWithAddress.setLastName("WithAddress");
        empWithAddress.setAddress(new Address());

        Employee empWithoutAddress = new Employee();
        empWithoutAddress.setFirstName(firstName);
        empWithoutAddress.setLastName("WithoutAddress");

        EntityManager em = createEntityManager();

        // make sure no Employee with the specified firstName exists.
        beginTransaction(em);
        try{
            em.createQuery("DELETE FROM Employee e WHERE e.firstName = '"+firstName+"'").executeUpdate();
            commitTransaction(em);
        }catch (RuntimeException ex){
            if (isTransactionActive(em)){
                rollbackTransaction(em);
            }
            closeEntityManager(em);
            throw ex;
        }

        // persist
        beginTransaction(em);
        try{
            em.persist(empWithAddress);
            em.persist(empWithoutAddress);
            commitTransaction(em);
        }catch (RuntimeException ex){
            if (isTransactionActive(em)){
                rollbackTransaction(em);
            }
            closeEntityManager(em);
            throw ex;
        }

        // clear cache
        clearCache();
        em.clear();

        // Find both to bring into the cache, delete empWithoutAddress.
        // Because the address VH is not triggered both objects should be invalidated.
        beginTransaction(em);
        try {
            Employee empWithAddressFound = em.find(Employee.class, empWithAddress.getId());
            empWithAddressFound.toString();
            Employee empWithoutAddressFound = em.find(Employee.class, empWithoutAddress.getId());
            empWithoutAddressFound.toString();
            em.createQuery("DELETE FROM Employee e WHERE e.firstName = '"+firstName+"' and e.address IS NULL").executeUpdate();
            commitTransaction(em);
        } catch (RuntimeException ex){
            if (isTransactionActive(em)){
                rollbackTransaction(em);
            }
            closeEntityManager(em);
            throw ex;
        }
        // we can no longer rely on the query above to clear the Employee from the persistence context.
        // Clearling the context to allow us to proceed.
        em.clear();
        // persist new empWithoutAddress - the one that has been deleted from the db.
        beginTransaction(em);
        try{
            Employee newEmpWithoutAddress = new Employee();
            newEmpWithoutAddress.setFirstName(firstName);
            newEmpWithoutAddress.setLastName("newWithoutAddress");
            newEmpWithoutAddress.setId(empWithoutAddress.getId());
            em.persist(newEmpWithoutAddress);
            commitTransaction(em);
        }catch (RuntimeException ex){
            if (isTransactionActive(em)){
                rollbackTransaction(em);
            }
            closeEntityManager(em);
            throw ex;
        }

        // persist new empWithAddress - the one still in the db.
        beginTransaction(em);
        try{
            Employee newEmpWithAddress = new Employee();
            newEmpWithAddress.setFirstName(firstName);
            newEmpWithAddress.setLastName("newWithAddress");
            newEmpWithAddress.setId(empWithAddress.getId());
            em.persist(newEmpWithAddress);
            fail("EntityExistsException was expected");
        } catch (EntityExistsException ex) {
            // "cant_persist_detatched_object" - ignore the expected exception
        } finally {
            rollbackTransaction(em);
        }

        // clean up
        beginTransaction(em);
        em.createQuery("DELETE FROM Employee e WHERE e.firstName = '"+firstName+"'").executeUpdate();
        commitTransaction(em);
        closeEntityManager(em);
    }

    public void testWRITELock(){
        // Cannot create parallel transactions.
        if (isOnServer()) {
            return;
        }
        EntityManager em = createEntityManager();
        Employee employee = new Employee();
        employee.setFirstName("Mark");
        employee.setLastName("Madsen");
        beginTransaction(em);
        try{
            em.persist(employee);
            commitTransaction(em);
        }catch (RuntimeException ex){
            if (isTransactionActive(em)){
                rollbackTransaction(em);
            }
            closeEntityManager(em);
            throw ex;
        }

        EntityManager em2 = createEntityManager();
        Exception optimisticLockException = null;

        beginTransaction(em);
        try{
            employee = em.find(Employee.class, employee.getId());
            em.lock(employee, LockModeType.WRITE);

            em2.getTransaction().begin();
            try{
                Employee employee2 = em2.find(Employee.class, employee.getId());
                employee2.setFirstName("Michael");
                em2.getTransaction().commit();
            }catch (RuntimeException ex){
                em2.getTransaction().rollback();
                throw ex;
            } finally {
                em2.close();
            }

            commitTransaction(em);
        } catch (RollbackException exception) {
            if (exception.getCause() instanceof OptimisticLockException){
                optimisticLockException = exception;
            }
        }catch (RuntimeException ex){
            if (isTransactionActive(em)){
                rollbackTransaction(em);
            }
            closeEntityManager(em);
            throw ex;
        }
        beginTransaction(em);
        try{
            employee = em.find(Employee.class, employee.getId());
            em.remove(employee);
            commitTransaction(em);
        }catch (RuntimeException ex){
            if (isTransactionActive(em)){
                rollbackTransaction(em);
            }
            throw ex;
        } finally {
            closeEntityManager(em);
        }

        if (optimisticLockException == null){
            fail("Proper exception not thrown when EntityManager.lock(object, WRITE) is used.");
        }
    }

    /*This test case uses the "broken-PU" PU defined in the persistence.xml
    located at eclipselink.jpa.test/resource/eclipselink-validation-failed-model/
    and included in eclipselink-validation-failed-model.jar */

    public void testEMFWrapValidationException()
    {
        // Comment out because it's not relevant for getDatabaseProperties() when running in server
        if (isOnServer()) {
            return;
        }
        try (JpaEntityManagerFactory factory = (JpaEntityManagerFactory) Persistence.createEntityManagerFactory("broken-PU", JUnitTestCaseHelper.getDatabaseProperties());
             JpaEntityManager em = (JpaEntityManager) factory.createEntityManager()) {
        } catch (jakarta.persistence.PersistenceException e)  {
            ArrayList expectedExceptions = new ArrayList();
            expectedExceptions.add(48);
            expectedExceptions.add(48);
            IntegrityException integrityException = (IntegrityException)e.getCause().getCause();
            Iterator i = integrityException.getIntegrityChecker().getCaughtExceptions().iterator();
            while (i.hasNext()){
                expectedExceptions.remove((Object)((EclipseLinkException)i.next()).getErrorCode());
            }
            if (expectedExceptions.size() > 0){
                fail("Not all expected exceptions were caught");
            }
        }
    }

    /**
     * At the time this test case was added, the problem it was designed to test for would cause a failure during deployement
     * and therefore this tests case would likely always pass if there is a successful deployment.
     * But it is anticipated that that may not always be the case and therefore we are adding a test case
     */
    public void testEMDefaultTxType()
    {
        // Comment out because it's not relevant for getDatabaseProperties() when running in server
        if (isOnServer()) {
            return;
        }
        EntityManagerFactory factory = null;
        try {
            factory = Persistence.createEntityManagerFactory("default1", JUnitTestCaseHelper.getDatabaseProperties());
            EntityManager em = factory.createEntityManager();
            em.close();
        } catch (Exception e)  {
            fail("Exception caught while creating EM with no \"transaction-type\" specified in persistence.xml");
        } finally {
            factory.close();
        }
        Assert.assertTrue(true);
    }

    public void testPersistOnNonEntity()
    {
        boolean testPass = false;
        Object nonEntity = new Object();
        EntityManager em = createEntityManager();
        beginTransaction(em);
        try {
            em.persist(nonEntity);
        } catch (IllegalArgumentException e) {
            testPass = true;
        } finally {
            rollbackTransaction(em);
        }
        Assert.assertTrue(testPass);
    }

    //detach(nonentity) throws illegalArgumentException
    public void testDetachNonEntity() {
        boolean testPass = false;
        Object nonEntity = new Object();
        EntityManager em = createEntityManager();
        beginTransaction(em);
        try {
            em.detach(nonEntity);
        } catch (IllegalArgumentException e) {
            testPass = true;
        } finally {
            rollbackTransaction(em);
        }
        Assert.assertTrue(testPass);
    }

    public void testClose() {
        // Close is not used on server.
        if (isOnServer()) {
            return;
        }
        EntityManager em = createEntityManager();
        if(!em.isOpen()) {
            fail("Created EntityManager is not open");
        }
        closeEntityManager(em);
        if(em.isOpen()) {
            fail("Closed EntityManager is still open");
        }
    }

    public void testBeginTransactionClose() {
        // Close is not used on server.
        if (isOnServer()) {
            return;
        }
        EntityManager em = createEntityManager();
        beginTransaction(em);
        try{
            closeEntityManager(em);
            if(em.isOpen()) {
                fail("Closed EntityManager is still open before transaction complete");
            }
        }catch (RuntimeException ex){
            if (isTransactionActive(em)){
                rollbackTransaction(em);
            }
            if(em.isOpen()) {
                closeEntityManager(em);
            }
            throw ex;
        }

        rollbackTransaction(em);
        if(em.isOpen()) {
            fail("Closed EntityManager is still open after transaction rollback");
        }
    }

    public void testBeginTransactionCloseCommitTransaction() {
        // EntityManager is always open in server.
        if (isOnServer()) {
            return;
        }
        String firstName = "testBeginTrCloseCommitTr";
        EntityManager em = createEntityManager();

        // make sure there is no employees with this firstName
        beginTransaction(em);
        Query q = em.createQuery("SELECT e FROM Employee e WHERE e.firstName = '"+firstName+"'");
        for (Object oldData : q.getResultList()) {
            em.remove(oldData);
        }
        commitTransaction(em);

        // create a new Employee
        Employee employee = new Employee();
        employee.setFirstName(firstName);

        // persist the new Employee and close the entity manager
        beginTransaction(em);
        try{
            em.persist(employee);
            closeEntityManager(em);
            if(em.isOpen()) {
                fail("Closed EntityManager is still open before transaction complete");
            }
        }catch (RuntimeException ex){
            rollbackTransaction(em);
            if(em.isOpen()) {
                closeEntityManager(em);
            }
            throw ex;
        }
        commitTransaction(em);

        if(em.isOpen()) {
            fail("Closed EntityManager is still open after transaction commit");
        }

        // verify that the employee has been persisted
        em = createEntityManager();
        RuntimeException exception = null;
        Employee persistedEmployee = null;
        try {
            persistedEmployee = (Employee)em.createQuery("SELECT OBJECT(e) FROM Employee e WHERE e.firstName = '"+firstName+"'").getSingleResult();
            persistedEmployee.toString();
        } catch (RuntimeException runtimeException) {
            exception = runtimeException;
        }

        // clean up
        beginTransaction(em);
        em.remove(persistedEmployee);
        commitTransaction(em);

        if(exception != null) {
            if(exception instanceof EntityNotFoundException) {
                fail("object has not been persisted");
            } else {
                // unexpected exception - rethrow.
                throw exception;
            }
        }
    }

    public void testBeginTransactionOnClosedEM() {
        if (isOnServer() && isJTA()) {
            // Uses EntityTransactions.
            return;
        }
        Exception expected = null;
        EntityManager em = createEntityManager();
        jakarta.persistence.EntityTransaction transaction= em.getTransaction();
        em.close();
        try {
            transaction.begin();
        } catch( IllegalStateException ise) {
            expected = ise;
        }
    }

    // The test removed because we moved back to binding literals
    // on platforms other than DB2 and Derby
/*    public void testDontBindLiteral() {
        EntityManager em = createEntityManager();

        Query controlQuery = em.createQuery("SELECT OBJECT(p) FROM SmallProject p WHERE p.name = CONCAT(:param1, :param2)");
        controlQuery.setParameter("param1", "A").setParameter("param2", "B");
        List controlResults = controlQuery.getResultList();
        int nControlParams = ((ExpressionQueryMechanism)((EJBQueryImpl)controlQuery).getDatabaseQuery().getQueryMechanism()).getCall().getParameters().size();
        if(nControlParams != 2) {
            fail("controlQuery has wrong number of parameters = "+nControlParams+"; 2 is expected");
        }

        Query query = em.createQuery("SELECT OBJECT(p) FROM SmallProject p WHERE p.name = CONCAT('A', 'B')");
        List results = query.getResultList();
        int nParams = ((ExpressionQueryMechanism)((EJBQueryImpl)query).getDatabaseQuery().getQueryMechanism()).getCall().getParameters().size();
        if(nParams > 0) {
            fail("Query processed literals as parameters");
        }

        closeEntityManager(em);
    }*/

    public void testPersistenceProperties() {
        // Different properties are used on the server.
        if (isOnServer()) {
            return;
        }

        EntityManager em = createEntityManager();
        ServerSession ss = ((org.eclipse.persistence.internal.jpa.EntityManagerImpl)em).getServerSession();

        // these properties were set in persistence unit
        // and overridden in CMP3TestModel.setup - the values should be overridden.

        boolean isReadShared = (ss.getReadConnectionPool() instanceof ReadConnectionPool);
        if(isReadShared != Boolean.parseBoolean((String)JUnitTestCaseHelper.propertiesMap.get(PersistenceUnitProperties.JDBC_READ_CONNECTIONS_SHARED))) {
            fail("isReadShared is wrong");
        }

        int writeMin = ss.getDefaultConnectionPool().getMinNumberOfConnections();
        if(writeMin != Integer.parseInt((String)JUnitTestCaseHelper.propertiesMap.get(PersistenceUnitProperties.JDBC_WRITE_CONNECTIONS_MIN))) {
            fail("writeMin is wrong");
        }

        int writeInitial = ss.getDefaultConnectionPool().getInitialNumberOfConnections();
        if(writeInitial != Integer.parseInt((String)JUnitTestCaseHelper.propertiesMap.get(PersistenceUnitProperties.JDBC_WRITE_CONNECTIONS_INITIAL))) {
            fail("writeInitial is wrong");
        }

        int writeMax = ss.getDefaultConnectionPool().getMaxNumberOfConnections();
        if(writeMax != Integer.parseInt((String)JUnitTestCaseHelper.propertiesMap.get(PersistenceUnitProperties.JDBC_WRITE_CONNECTIONS_MAX))) {
            fail("writeMax is wrong");
        }

        int readMin = ss.getReadConnectionPool().getMinNumberOfConnections();
        if(readMin != Integer.parseInt((String)JUnitTestCaseHelper.propertiesMap.get(PersistenceUnitProperties.JDBC_READ_CONNECTIONS_MIN))) {
            fail("readMin is wrong");
        }

        int readMax = ss.getReadConnectionPool().getMaxNumberOfConnections();
        if(readMax != Integer.parseInt((String)JUnitTestCaseHelper.propertiesMap.get(PersistenceUnitProperties.JDBC_READ_CONNECTIONS_MAX))) {
            fail("readMax is wrong");
        }

        int batchSize = ss.getPlatform().getMaxBatchWritingSize();
        if (batchSize != Integer.parseInt((String)JUnitTestCaseHelper.propertiesMap.get(PersistenceUnitProperties.BATCH_WRITING_SIZE))) {
            fail("batchSize is wrong");
        }

        // these properties were set in persistence unit - the values should be the same as in persistence.xml
        /*
            <property name="eclipselink.session-name" value="default-session"/>
            <property name="eclipselink.cache.size.default" value="500"/>
            <property name="eclipselink.cache.size.Employee" value="550"/>
            <property name="eclipselink.cache.size.org.eclipse.persistence.testing.models.jpa.advanced.Address" value="555"/>
            <property name="eclipselink.cache.type.default" value="Full"/>
            <property name="eclipselink.cache.type.Employee" value="Weak"/>
            <property name="eclipselink.cache.type.org.eclipse.persistence.testing.models.jpa.advanced.Address" value="HardWeak"/>
            <property name="eclipselink.session.customizer" value="org.eclipse.persistence.testing.models.jpa.advanced.Customizer"/>
            <property name="eclipselink.descriptor.customizer.Employee" value="org.eclipse.persistence.testing.models.jpa.advanced.Customizer"/>
            <property name="eclipselink.descriptor.customizer.org.eclipse.persistence.testing.models.jpa.advanced.Address" value="org.eclipse.persistence.testing.models.jpa.advanced.Customizer"/>
            <property name="eclipselink.descriptor.customizer.Project" value="org.eclipse.persistence.testing.models.jpa.advanced.Customizer"/>
        */

        String sessionName = ss.getName();
        if(!sessionName.equals("default-session")) {
            fail("sessionName is wrong: "+sessionName);
        }

        int defaultCacheSize = ss.getDescriptor(Project.class).getIdentityMapSize();
        if(defaultCacheSize != 500) {
            fail("defaultCacheSize is wrong: "+defaultCacheSize);
        }

        int employeeCacheSize = ss.getDescriptor(Employee.class).getIdentityMapSize();
        if(employeeCacheSize != 550) {
            fail("employeeCacheSize is wrong: "+employeeCacheSize);
        }

        int addressCacheSize = ss.getDescriptor(Address.class).getIdentityMapSize();
        if(addressCacheSize != 555) {
            fail("addressCacheSize is wrong: "+addressCacheSize);
        }

        // Department cache size specified in @Cache annotation - that should override default property
        int departmentCacheSize = ss.getDescriptor(Department.class).getIdentityMapSize();
        if(departmentCacheSize != 777) {
            fail("departmentCacheSize is wrong: "+departmentCacheSize);
        }

        Class defaultCacheType = ss.getDescriptor(Project.class).getIdentityMapClass();
        if(! Helper.getShortClassName(defaultCacheType).equals("FullIdentityMap")) {
            fail("defaultCacheType is wrong: "+Helper.getShortClassName(defaultCacheType));
        }

        Class employeeCacheType = ss.getDescriptor(Employee.class).getIdentityMapClass();
        if(! Helper.getShortClassName(employeeCacheType).equals("WeakIdentityMap")) {
            fail("employeeCacheType is wrong: "+Helper.getShortClassName(employeeCacheType));
        }

        Class addressCacheType = ss.getDescriptor(Address.class).getIdentityMapClass();
        if(! Helper.getShortClassName(addressCacheType).equals("HardCacheWeakIdentityMap")) {
            fail("addressCacheType is wrong: "+Helper.getShortClassName(addressCacheType));
        }

        // Department cache type specified in @Cache annotation - that should override default property
        Class departmentCacheType = ss.getDescriptor(Department.class).getIdentityMapClass();
        if(! Helper.getShortClassName(departmentCacheType).equals("SoftCacheWeakIdentityMap")) {
            fail("departmentCacheType is wrong: "+Helper.getShortClassName(departmentCacheType));
        }

        int numSessionCalls = Customizer.getNumberOfCallsForSession(ss.getName());
        if(numSessionCalls == 0) {
            fail("session customizer hasn't been called");
        }

        int numProjectCalls = Customizer.getNumberOfCallsForClass(Project.class.getName());
        if(numProjectCalls == 0) {
            fail("Project customizer hasn't been called");
        }

        int numEmployeeCalls = Customizer.getNumberOfCallsForClass(Employee.class.getName());
        if(numEmployeeCalls == 0) {
            fail("Employee customizer hasn't been called");
        }

        int numAddressCalls = Customizer.getNumberOfCallsForClass(Address.class.getName());
        if(numAddressCalls == 0) {
            fail("Address customizer hasn't been called");
        }

        IdValidation employeeIdValidation = ss.getDescriptor(Employee.class).getIdValidation();
        if(employeeIdValidation != IdValidation.ZERO) {
            fail("employeeIdValidation is wrong, IdValidation.ZERO assigned through PrimaryKey annotation was expected");
        }

        IdValidation addressIdValidation = ss.getDescriptor(Address.class).getIdValidation();
        if(addressIdValidation != IdValidation.NEGATIVE) {
            fail("addressIdValidation is wrong, IdValidation.NEGATIVE set as a default value in persistence.xml was expected");
        }

        closeEntityManager(em);
    }

    public void testGetLockModeType() {
        if ((JUnitTestCase.getServerSession()).getPlatform().isSymfoware()) {
            getServerSession().logMessage("Test testGetLockModeType skipped for this platform, "
                    + "Symfoware doesn't support UpdateAll/DeleteAll on multi-table objects (see rfe 298193).");
            return;
        }
        if (isSelectForUpateSupported()) {
            EntityManager em = createEntityManager();
            try {
                beginTransaction(em);
                Employee emp = new Employee();
                Employee emp1 = new Employee();
                Employee emp2 = new Employee();
                Employee emp3 = new Employee();
                Employee emp4 = new Employee();
                Employee emp5 = new Employee();
                Employee emp6= new Employee();
                Employee emp7= new Employee();
                emp.setFirstName("Douglas");
                emp.setLastName("McRae");
                emp1.setFirstName("kaul");
                emp1.setLastName("Jeet");
                emp2.setFirstName("Schwatz");
                emp2.setLastName("Jonathan");
                emp3.setFirstName("Anil");
                emp3.setLastName("Gadre");
                emp4.setFirstName("Anil");
                emp4.setLastName("Gaur");
                emp5.setFirstName("Eliot");
                emp5.setLastName("Morrison");
                emp6.setFirstName("Edward");
                emp6.setLastName("Bratt");
                emp7.setFirstName("TJ");
                emp7.setLastName("Thomas");
                em.persist(emp);
                em.persist(emp1);
                em.persist(emp2);
                em.persist(emp3);
                em.persist(emp4);
                em.persist(emp5);
                em.persist(emp6);
                em.persist(emp7);
                commitTransaction(em);
                beginTransaction(em);
                emp = em.find(Employee.class, emp.getId());
                emp1 = em.find(Employee.class, emp1.getId());
                emp2 = em.find(Employee.class, emp2.getId());
                emp3 = em.find(Employee.class, emp3.getId());
                emp4 = em.find(Employee.class, emp4.getId());
                emp5 = em.find(Employee.class, emp5.getId());
                emp6 = em.find(Employee.class, emp6.getId());
                emp7 = em.find(Employee.class, emp7.getId());
                em.lock(emp, LockModeType.OPTIMISTIC);
                LockModeType lt = em.getLockMode(emp);
                em.lock(emp1, LockModeType.OPTIMISTIC_FORCE_INCREMENT);
                LockModeType lt1 = em.getLockMode(emp1);
                em.lock(emp5, LockModeType.READ);
                LockModeType lt5 = em.getLockMode(emp5);
                em.lock(emp6, LockModeType.WRITE);
                LockModeType lt6 = em.getLockMode(emp6);
                em.lock(emp7, LockModeType.NONE);
                LockModeType lt7 = em.getLockMode(emp7);
                assertEquals("Did not return correct LockModeType", LockModeType.OPTIMISTIC, lt);
                assertEquals("Did not return correct LockModeType", LockModeType.OPTIMISTIC_FORCE_INCREMENT, lt1);
                assertEquals("Did not return correct LockModeType", LockModeType.OPTIMISTIC, lt5);
                assertEquals("Did not return correct LockModeType", LockModeType.OPTIMISTIC_FORCE_INCREMENT, lt6);
                assertEquals("Did not return correct LockModeType", LockModeType.NONE, lt7);

                // HANA doesn't support pessimistic locking with queries on multiple tables
                if (!getServerSession().getPlatform().isHANA()) {
                    em.lock(emp2, LockModeType.PESSIMISTIC_READ);
                    LockModeType lt2 = em.getLockMode(emp2);
                    em.lock(emp3, LockModeType.PESSIMISTIC_WRITE);
                    LockModeType lt3 = em.getLockMode(emp3);
                    em.lock(emp4, LockModeType.PESSIMISTIC_FORCE_INCREMENT);
                    LockModeType lt4 = em.getLockMode(emp4);

                    // Note: On some databases EclipseLink automatically upgrade LockModeType to PESSIMSITIC_WRITE
                    assertTrue("Did not return correct LockModeType", lt2 == LockModeType.PESSIMISTIC_WRITE || lt2 == LockModeType.PESSIMISTIC_READ);

                    assertEquals("Did not return correct LockModeType", LockModeType.PESSIMISTIC_WRITE, lt3);
                    assertEquals("Did not return correct LockModeType", LockModeType.PESSIMISTIC_FORCE_INCREMENT, lt4);
                }

            } catch (UnsupportedOperationException use) {
                return;
            } finally {
                rollbackTransaction(em);
                closeEntityManager(em);
            }
        }
    }

    //'getProperties()' returns map that throws exception when tried to modify.
    public void testGetProperties() {
        EntityManager em = createEntityManager();
        beginTransaction(em);
        try {
            Map m1 = em.getProperties();
            m1.remove("eclipselink.weaving");
        } catch (UnsupportedOperationException use) {
            return;
        } catch (Exception e) {
            fail("Wrong exception type thrown: " + e.getClass());
        } finally {
            rollbackTransaction(em);
            closeEntityManager(em);
        }
        fail("No exception thrown when entityManager's properties are attempted to change.");
    }

    public void testUOWReferenceInExpressionCache() {
        // Properties only works in jse.
        if (isOnServer()) {
            return;
        }
        EntityManager manager = createEntityManager();
        ((JpaEntityManager)manager).getUnitOfWork().getParent().getIdentityMapAccessor().initializeAllIdentityMaps();
        DescriptorQueryManager queryManager = ((JpaEntityManager)manager).getUnitOfWork().getDescriptor(Employee.class).getQueryManager();
        queryManager.setExpressionQueryCacheMaxSize(queryManager.getExpressionQueryCacheMaxSize());
        ReadAllQuery query = new ReadAllQuery();
        query.setIsExecutionClone(true);
        query.setReferenceClass(Employee.class);
        ((JpaEntityManager)manager).getUnitOfWork().executeQuery(query);
        closeEntityManager(manager);

        assertNull("ExpressionCache has query that references a RWUOW", queryManager.getCachedExpressionQuery(query).getSession());
    }

/*    public void testUnsynchronizedPC(){
        if (isOnServer()){
            EntityManager em = createEntityManager(true);
            beginTransaction(em);
            EntityManagerImpl emImpl = em.unwrap(EntityManagerImpl.class);
            emImpl.getAbstractSession(); // force the active PC to be loaded
            assertTrue("PC was automatically joined to transaction when created. This should not be the case for Unsynchronized", !em.isJoinedToTransaction());
            List<Employee> result = em.createQuery("select e from employee e").getResultList();
            result.get(0).setFirstName(System.currentTimeMillis() + "####");
            List<Employee> secondResult = em.createQuery("select e from employee e where e.firstName LIKE '%####%'").getResultList();
            assertTrue("Flushed changes to database when em was unjoined", secondResult.isEmpty());
            assertTrue("PC was automatically joined to transaction when find was issued. This should not be the case for Unsynchronized", !em.isJoinedToTransaction());
            try{
                em.flush();
                fail("flush did not throw txn required exception when em was not joined to transcation");
            }catch(TransactionRequiredException txr){

            }
            em.joinTransaction();
            assertTrue("PC was not joined to transaction when joinTransaction was called", em.isJoinedToTransaction());
            try{
                em.flush();
            }catch(TransactionRequiredException txr){
                fail("txn required exception when em was joined to transcation");
            }
            rollbackTransaction(em);
        }


    }
*/
    public void testUnWrapClass() {
        EntityManager em = createEntityManager();
        try {
            beginTransaction(em);
            EntityManagerImpl emi = (EntityManagerImpl) em.getDelegate();
            ServerSession session = emi.getServerSession();
            UnitOfWork uow = emi.getUnitOfWork();
            JpaEntityManager jem = emi;
            org.eclipse.persistence.sessions.server.ServerSession session1;
            session1 = (ServerSession) em.unwrap(org.eclipse.persistence.sessions.Session.class);
            assertEquals("Does not return server session", session, session1);
            UnitOfWork uow1;
            uow1 = em.unwrap(org.eclipse.persistence.sessions.UnitOfWork.class);
            assertEquals("Does not return unit of work", uow, uow1);
            JpaEntityManager jem1 = em.unwrap(org.eclipse.persistence.jpa.JpaEntityManager.class);
            assertEquals("Does not return underlying entitymanager", jem, jem1);

            Connection conn1 = em.unwrap(java.sql.Connection.class);
            assertNotNull("Connection returned was null", conn1);
            // TODO: This should be supported.
            /*Connection conn = uowImpl.getAccessor().getConnection();
            assertEquals("Does not return underlying connection", conn, conn1);*/
        } finally {
            rollbackTransaction(em);
            closeEntityManager(em);
        }
    }

    public void testMultipleFactories() {
        getEntityManagerFactory();
        closeEntityManagerFactory();
        boolean isOpen = getEntityManagerFactory().isOpen();
        if(!isOpen) {
            fail("Close factory 1; open factory 2 - it's not open");
        } else {
            // Get entity manager just to login back the session, then close em
            getEntityManagerFactory().createEntityManager().close();
        }
    }

    /**
     * The same persistence unit in the server should have the same session for container or application managed.
     */
    public void testApplicationManagedInServer() {
        EntityManagerFactoryImpl factory;
        if (getServerPlatform().isWeblogic()) {
            HashMap<String, String> properties = new HashMap<>();
            String applicationId = "eclipselink-advanced-model";
            ServerPlatform serverPlatform = getServerSession().getServerPlatform();
            if (serverPlatform.usesPartitions()) {
                WebLogic_12_Platform webLogic12Platform = (WebLogic_12_Platform) serverPlatform;
                if (!webLogic12Platform.isGlobalRuntime()) {
                    applicationId += ("$" + webLogic12Platform.getPartitionName());
                }
            }
            properties.put("weblogic.application-id", applicationId);
            factory = (EntityManagerFactoryImpl) Persistence.createEntityManagerFactory("default", properties);
        } else {
            factory = (EntityManagerFactoryImpl) Persistence.createEntityManagerFactory("default");
        }
        
        try {
            if (getDatabaseSession() != factory.getServerSession()) {
                fail("Application managed persistence unit is not the same as the container managed session.  Deployment is broken."
                        + getDatabaseSession().getName() + " != " + factory.getServerSession().getName());
            }
        } finally {
            factory.close();
        }
    }

    public void testMultipleExistenceChecksForDetachedObjects() {
        EntityManager em = createEntityManager();
        Department dept1 = new Department("Dept1");
        Department dept2 = new Department("Dept2");
        Department dept3 = new Department("DetachedDept");
        Employee emp = new Employee("Bob", "Bob");

        try {
            List<Address> results = em.createQuery("Select a from Address a").getResultList();
            beginTransaction(em);
            em.persist(emp);
            em.persist(dept1);
            em.persist(dept2);
            commitTransaction(em);
            em.clear();

            beginTransaction(em);
            emp = em.find(Employee.class, emp.getId());
            emp.setDepartment(dept2);
            em.flush();
            em.persist(dept3);
            emp.setDepartment(dept3);
            em.flush();
            emp.setDepartment(dept1);
            em.flush();
            commitTransaction(em);
            closeEntityManager(em);
            verifyObjectInCacheAndDatabase(emp);
        } finally {
            try {
                em = createEntityManager();
                beginTransaction(em);
                em.remove(em.find(Department.class, dept1.getId()));
                em.remove(em.find(Department.class, dept2.getId()));
                em.remove(em.find(Department.class, dept3.getId()));
                em.remove(em.find(Employee.class, emp.getId()));
                commitTransaction(em);
            } catch (Exception e) {//ignore
            }
        }
    }

    public void testParallelMultipleFactories() {
        if (isOnServer()) {
            // Cannot connect locally on server.
            return;
        }
        EntityManagerFactory factory1 =  Persistence.createEntityManagerFactory("default", JUnitTestCaseHelper.getDatabaseProperties());
        factory1.createEntityManager();
        EntityManagerFactory factory2 =  Persistence.createEntityManagerFactory("default", JUnitTestCaseHelper.getDatabaseProperties());
        factory2.createEntityManager();
        factory1.close();
        if(factory1.isOpen()) {
            fail("after factory1.close() factory1 is not closed");
        }
        if(!factory2.isOpen()) {
            fail("after factory1.close() factory2 is closed");
        }
        factory2.close();
        if(factory2.isOpen()) {
            fail("after factory2.close() factory2 is not closed");
        }
        EntityManagerFactory factory3 =  Persistence.createEntityManagerFactory("default", JUnitTestCaseHelper.getDatabaseProperties());
        if(!factory3.isOpen()) {
            fail("factory3 is closed");
        }
        factory3.createEntityManager();
        factory3.close();
        if(factory3.isOpen()) {
            fail("after factory3.close() factory3 is open");
        }
    }

    public void testQueryHints() {
        EntityManager em = (EntityManager)getEntityManagerFactory().createEntityManager().getDelegate();
        Query query = em.createQuery("SELECT OBJECT(e) FROM Employee e WHERE e.firstName = 'testQueryHints'");
        // Set a hint first to trigger query clone (because query is accessed before other hints are set).
        query.setHint(QueryHints.READ_ONLY, false);
        ObjectLevelReadQuery olrQuery = (ObjectLevelReadQuery)((JpaQuery)query).getDatabaseQuery();

        // binding
        // original state = default state
        assertTrue(olrQuery.shouldIgnoreBindAllParameters());
        // set boolean true
        query.setHint(QueryHints.BIND_PARAMETERS, true);
        // Parse cached query may be cloned when hint set, so re-get.
        olrQuery = (ObjectLevelReadQuery)((EJBQueryImpl)query).getDatabaseQuery();
        assertTrue("Binding not set.", olrQuery.shouldBindAllParameters());
        // reset to original state
        query.setHint(QueryHints.BIND_PARAMETERS, "");
        assertTrue("Binding not set.", olrQuery.shouldIgnoreBindAllParameters());
        // set "false"
        query.setHint(QueryHints.BIND_PARAMETERS, "false");
        assertFalse("Binding not set.", olrQuery.shouldBindAllParameters());
        // reset to the original state
        query.setHint(QueryHints.BIND_PARAMETERS, "");
        assertTrue("Binding not set.", olrQuery.shouldIgnoreBindAllParameters());

        // cache usage
        query.setHint(QueryHints.CACHE_USAGE, CacheUsage.DoNotCheckCache);
        assertTrue("Cache usage not set.", olrQuery.getCacheUsage()==ObjectLevelReadQuery.DoNotCheckCache);
        query.setHint(QueryHints.CACHE_USAGE, CacheUsage.CheckCacheOnly);
        assertTrue("Cache usage not set.", olrQuery.shouldCheckCacheOnly());
        query.setHint(QueryHints.CACHE_USAGE, CacheUsage.ConformResultsInUnitOfWork);
        assertTrue("Cache usage not set.", olrQuery.shouldConformResultsInUnitOfWork());

        query.setHint(QueryHints.INDIRECTION_POLICY, CacheUsageIndirectionPolicy.Trigger);
        assertTrue("INDIRECTION_POLICY not set.", olrQuery.getInMemoryQueryIndirectionPolicyState() == InMemoryQueryIndirectionPolicy.SHOULD_TRIGGER_INDIRECTION);

        // reset to the original state
        query.setHint(QueryHints.CACHE_USAGE, "");
        assertTrue("Cache usage not set.", olrQuery.shouldCheckDescriptorForCacheUsage());

        // pessimistic lock
        query.setHint(QueryHints.PESSIMISTIC_LOCK, PessimisticLock.Lock);
        assertTrue("Lock not set.", olrQuery.getLockMode()==ObjectLevelReadQuery.LOCK);
        query.setHint(QueryHints.PESSIMISTIC_LOCK, PessimisticLock.NoLock);
        assertTrue("Lock not set.", olrQuery.getLockMode()==ObjectLevelReadQuery.NO_LOCK);
        query.setHint(QueryHints.PESSIMISTIC_LOCK, PessimisticLock.LockNoWait);
        assertTrue("Lock not set.", olrQuery.getLockMode()==ObjectLevelReadQuery.LOCK_NOWAIT);
        // default state
        query.setHint(QueryHints.PESSIMISTIC_LOCK, "");
        assertTrue("Lock not set.", olrQuery.getLockMode()==ObjectLevelReadQuery.NO_LOCK);

        //refresh
        // set to original state - don't refresh.
        // the previously run LOCK and LOCK_NOWAIT have swithed it to true
        query.setHint(QueryHints.REFRESH, false);
        assertFalse("Refresh not set.", olrQuery.shouldRefreshIdentityMapResult());
        // set boolean true
        query.setHint(QueryHints.REFRESH, true);
        assertTrue("Refresh not set.", olrQuery.shouldRefreshIdentityMapResult());
        assertTrue("CascadeByMapping not set.", olrQuery.shouldCascadeByMapping()); // check if cascade refresh is enabled
        // set "false"
        query.setHint(QueryHints.REFRESH, "false");
        assertFalse("Refresh not set.", olrQuery.shouldRefreshIdentityMapResult());
        // set Boolean.TRUE
        query.setHint(QueryHints.REFRESH, Boolean.TRUE);
        assertTrue("Refresh not set.", olrQuery.shouldRefreshIdentityMapResult());
        assertTrue("CascadeByMapping not set.", olrQuery.shouldCascadeByMapping()); // check if cascade refresh is enabled
        // reset to original state
        query.setHint(QueryHints.REFRESH, "");
        assertFalse("Refresh not set.", olrQuery.shouldRefreshIdentityMapResult());

        // Read-only
        query.setHint(QueryHints.READ_ONLY, "false");
        assertFalse("Read-only not set.", olrQuery.isReadOnly());

        query.setHint(QueryHints.READ_ONLY, Boolean.TRUE);
        assertTrue("Read-only not set.", olrQuery.isReadOnly());

        query.setHint(QueryHints.READ_ONLY, Boolean.FALSE);
        assertFalse("Read-only not set.", olrQuery.isReadOnly());

        // Maintain cache
        query.setHint(QueryHints.MAINTAIN_CACHE, true);
        assertTrue("MAINTAIN_CACHE set.", olrQuery.shouldMaintainCache());

        query.setHint(QueryHints.MAINTAIN_CACHE, "false");
        assertFalse("MAINTAIN_CACHE not set.", olrQuery.shouldMaintainCache());

        query.setHint(QueryHints.MAINTAIN_CACHE, Boolean.TRUE);
        assertTrue("MAINTAIN_CACHE not set.", olrQuery.shouldMaintainCache());

        query.setHint(QueryHints.MAINTAIN_CACHE, Boolean.FALSE);
        assertFalse("MAINTAIN_CACHE not set.", olrQuery.shouldMaintainCache());

        // Prepare
        query.setHint(QueryHints.PREPARE, true);
        assertTrue("PREPARE set.", olrQuery.shouldPrepare());

        query.setHint(QueryHints.PREPARE, "false");
        assertFalse("PREPARE not set.", olrQuery.shouldPrepare());

        query.setHint(QueryHints.PREPARE, Boolean.TRUE);
        assertTrue("PREPARE not set.", olrQuery.shouldPrepare());

        query.setHint(QueryHints.PREPARE, Boolean.FALSE);
        assertFalse("PREPARE not set.", olrQuery.shouldPrepare());

        // Cache statement
        query.setHint(QueryHints.CACHE_STATMENT, true);
        assertTrue("CACHE_STATMENT set.", olrQuery.shouldCacheStatement());

        query.setHint(QueryHints.CACHE_STATMENT, "false");
        assertFalse("CACHE_STATMENT not set.", olrQuery.shouldCacheStatement());

        query.setHint(QueryHints.CACHE_STATMENT, Boolean.TRUE);
        assertTrue("CACHE_STATMENT not set.", olrQuery.shouldCacheStatement());

        query.setHint(QueryHints.CACHE_STATMENT, Boolean.FALSE);
        assertFalse("CACHE_STATMENT not set.", olrQuery.shouldCacheStatement());

        // Flush
        query.setHint(QueryHints.FLUSH, true);
        assertTrue("FLUSH set.", olrQuery.getFlushOnExecute());

        query.setHint(QueryHints.FLUSH, "false");
        assertFalse("FLUSH not set.", olrQuery.getFlushOnExecute());

        query.setHint(QueryHints.FLUSH, Boolean.TRUE);
        assertTrue("FLUSH not set.", olrQuery.getFlushOnExecute());

        query.setHint(QueryHints.FLUSH, Boolean.FALSE);
        assertFalse("FLUSH not set.", olrQuery.getFlushOnExecute());

        // Native connection
        query.setHint(QueryHints.NATIVE_CONNECTION, true);
        assertTrue("NATIVE_CONNECTION set.", olrQuery.isNativeConnectionRequired());

        query.setHint(QueryHints.NATIVE_CONNECTION, "false");
        assertFalse("NATIVE_CONNECTION not set.", olrQuery.isNativeConnectionRequired());

        query.setHint(QueryHints.NATIVE_CONNECTION, Boolean.TRUE);
        assertTrue("NATIVE_CONNECTION not set.", olrQuery.isNativeConnectionRequired());

        query.setHint(QueryHints.NATIVE_CONNECTION, Boolean.FALSE);
        assertFalse("NATIVE_CONNECTION not set.", olrQuery.isNativeConnectionRequired());

        // Hint
        query.setHint(QueryHints.HINT, "/* use the index man */");
        assertTrue("HINT not set.", olrQuery.getHintString().equals("/* use the index man */"));

        // Cursor
        query.setHint(QueryHints.CURSOR, Boolean.TRUE);
        assertTrue("CURSOR not set.", ((ReadAllQuery)olrQuery).getContainerPolicy().isCursoredStreamPolicy());

        query.setHint(QueryHints.CURSOR, Boolean.FALSE);
        assertFalse("CURSOR set.", ((ReadAllQuery)olrQuery).getContainerPolicy().isCursoredStreamPolicy());

        query.setHint(QueryHints.CURSOR_INITIAL_SIZE, "100");
        assertTrue("CURSOR not set.", ((ReadAllQuery)olrQuery).getContainerPolicy().isCursoredStreamPolicy());
        assertTrue("CURSOR_INITIAL_SIZE not set.", ((CursoredStreamPolicy)((ReadAllQuery)olrQuery).getContainerPolicy()).getInitialReadSize() == 100);

        query.setHint(QueryHints.CURSOR_INITIAL_SIZE, 200);
        assertTrue("CURSOR_INITIAL_SIZE not set.", ((CursoredStreamPolicy)((ReadAllQuery)olrQuery).getContainerPolicy()).getInitialReadSize() == 200);

        query.setHint(QueryHints.CURSOR, Boolean.FALSE);

        query.setHint(QueryHints.CURSOR_PAGE_SIZE, "100");
        assertTrue("CURSOR not set.", ((ReadAllQuery)olrQuery).getContainerPolicy().isCursoredStreamPolicy());
        assertTrue("CURSOR_PAGE_SIZE not set.", ((CursoredStreamPolicy)((ReadAllQuery)olrQuery).getContainerPolicy()).getPageSize() == 100);

        query.setHint(QueryHints.CURSOR_PAGE_SIZE, 200);
        assertTrue("CURSOR_PAGE_SIZE not set.", ((CursoredStreamPolicy)((ReadAllQuery)olrQuery).getContainerPolicy()).getPageSize() == 200);

        query.setHint(QueryHints.CURSOR, Boolean.FALSE);

        query.setHint(QueryHints.CURSOR_SIZE, "Select Count(*) from Employee");
        assertTrue("CURSOR_SIZE not set.", ((CursoredStreamPolicy)((ReadAllQuery)olrQuery).getContainerPolicy()).getSizeQuery().getSQLString().equals("Select Count(*) from Employee"));

        // Scrollable cursor
        query.setHint(QueryHints.SCROLLABLE_CURSOR, Boolean.TRUE);
        assertTrue("SCROLLABLE_CURSOR not set.", ((ReadAllQuery)olrQuery).getContainerPolicy().isScrollableCursorPolicy());

        query.setHint(QueryHints.SCROLLABLE_CURSOR, Boolean.FALSE);
        assertFalse("SCROLLABLE_CURSOR set.", ((ReadAllQuery)olrQuery).getContainerPolicy().isScrollableCursorPolicy());

        query.setHint(QueryHints.RESULT_SET_TYPE, ResultSetType.Reverse);
        assertTrue("RESULT_SET_TYPE not set.", ((ScrollableCursorPolicy)((ReadAllQuery)olrQuery).getContainerPolicy()).getResultSetType() == ScrollableCursorPolicy.FETCH_REVERSE);

        query.setHint(QueryHints.RESULT_SET_CONCURRENCY, ResultSetConcurrency.Updatable);
        assertTrue("RESULT_SET_CONCURRENCY not set.", ((ScrollableCursorPolicy)((ReadAllQuery)olrQuery).getContainerPolicy()).getResultSetConcurrency() == ScrollableCursorPolicy.CONCUR_UPDATABLE);

        // Exclusive connection
        query.setHint(QueryHints.EXCLUSIVE_CONNECTION, Boolean.TRUE);
        assertTrue("EXCLUSIVE_CONNECTION not set.", olrQuery.shouldUseExclusiveConnection());

        // Inheritance
        query.setHint(QueryHints.INHERITANCE_OUTER_JOIN, Boolean.TRUE);
        assertTrue("INHERITANCE_OUTER_JOIN not set.", olrQuery.shouldOuterJoinSubclasses());

        // History
        query.setHint(QueryHints.AS_OF, "1973/10/11 12:00:00");
        assertTrue("AS_OF not set.", olrQuery.getAsOfClause() != null);

        query.setHint(QueryHints.AS_OF_SCN, "12345");
        assertTrue("AS_OF_SCN not set.", ((Number)olrQuery.getAsOfClause().getValue()).intValue() == 12345);

        // Fetch groups
        query.setHint(QueryHints.FETCH_GROUP_DEFAULT, Boolean.FALSE);
        assertFalse("FETCH_GROUP_DEFAULT not set.", olrQuery.shouldUseDefaultFetchGroup());

        query.setHint(QueryHints.FETCH_GROUP_NAME, "nameAndCity");
        assertTrue("FETCH_GROUP_NAME not set.", olrQuery.getFetchGroupName().equals("nameAndCity"));

        query.setHint(QueryHints.FETCH_GROUP_ATTRIBUTE, "firstName");
        query.setHint(QueryHints.FETCH_GROUP_ATTRIBUTE, "lastName");
        assertTrue("FETCH_GROUP_ATTRIBUTE not set.", olrQuery.getFetchGroup().containsAttribute("firstName"));
        assertTrue("FETCH_GROUP_ATTRIBUTE not set.", olrQuery.getFetchGroup().containsAttribute("lastName"));

        FetchGroup fetchGroup = new FetchGroup();
        fetchGroup.addAttribute("id");
        query.setHint(QueryHints.FETCH_GROUP, fetchGroup);
        assertTrue("FETCH_GROUP not set.", olrQuery.getFetchGroup() == fetchGroup);

        // Timeout
        query.setHint(QueryHints.JDBC_TIMEOUT, 100);
        assertTrue("Timeout not set.", olrQuery.getQueryTimeout() == 100);

        // JDBC
        query.setHint(QueryHints.JDBC_FETCH_SIZE, 101);
        assertTrue("Fetch-size not set.", olrQuery.getFetchSize() == 101);

        query.setHint(QueryHints.JDBC_MAX_ROWS, 103);
        assertTrue("Max-rows not set.", olrQuery.getMaxRows() == 103);

        query.setHint(QueryHints.JDBC_FIRST_RESULT, 123);
        assertTrue("JDBC_FIRST_RESULT not set.", olrQuery.getFirstResult() == 123);

        // Refresh
        query.setHint(QueryHints.REFRESH_CASCADE, CascadePolicy.NoCascading);
        assertTrue(olrQuery.getCascadePolicy()==DatabaseQuery.NoCascading);
        query.setHint(QueryHints.REFRESH_CASCADE, CascadePolicy.CascadeByMapping);
        assertTrue(olrQuery.getCascadePolicy()==DatabaseQuery.CascadeByMapping);
        query.setHint(QueryHints.REFRESH_CASCADE, CascadePolicy.CascadeAllParts);
        assertTrue(olrQuery.getCascadePolicy()==DatabaseQuery.CascadeAllParts);
        query.setHint(QueryHints.REFRESH_CASCADE, CascadePolicy.CascadePrivateParts);
        assertTrue(olrQuery.getCascadePolicy()==DatabaseQuery.CascadePrivateParts);
        // reset to the original state
        query.setHint(QueryHints.REFRESH_CASCADE, "");
        assertTrue(olrQuery.getCascadePolicy()==DatabaseQuery.CascadeByMapping);

        // Result collection
        query.setHint(QueryHints.RESULT_COLLECTION_TYPE, java.util.ArrayList.class);
        assertTrue("ArrayList not set.", ((ReadAllQuery)olrQuery).getContainerPolicy().getContainerClass().equals(java.util.ArrayList.class));

        query.setHint(QueryHints.RESULT_COLLECTION_TYPE, "java.util.Vector");
        assertTrue("Vector not set.", ((ReadAllQuery)olrQuery).getContainerPolicy().getContainerClass().equals(java.util.Vector.class));

        query.setHint(QueryHints.RESULT_COLLECTION_TYPE, "org.eclipse.persistence.testing.models.jpa.relationships.CustomerCollection");
        assertTrue("CustomerCollection not set.", ((ReadAllQuery)olrQuery).getContainerPolicy().getContainerClass().equals(CustomerCollection.class));

        // Query type
        query.setHint(QueryHints.QUERY_TYPE, QueryType.ReadObject);
        assertTrue("QUERY_TYPE not set.", ((JpaQuery)query).getDatabaseQuery().getClass().equals(ReadObjectQuery.class));

        query.setHint(QueryHints.QUERY_TYPE, QueryType.Report);
        assertTrue("QUERY_TYPE not set.", ((JpaQuery)query).getDatabaseQuery().getClass().equals(ReportQuery.class));

        query.setHint(QueryHints.QUERY_TYPE, QueryType.DataModify);
        assertTrue("QUERY_TYPE not set.", ((JpaQuery)query).getDatabaseQuery().getClass().equals(DataModifyQuery.class));

        query.setHint(QueryHints.QUERY_TYPE, "org.eclipse.persistence.queries.ValueReadQuery");
        assertTrue("QUERY_TYPE not set.", ((JpaQuery)query).getDatabaseQuery().getClass().equals(ValueReadQuery.class));

        query.setHint(QueryHints.QUERY_TYPE, QueryType.ReadAll);
        assertTrue("QUERY_TYPE not set.", ((JpaQuery)query).getDatabaseQuery().getClass().equals(ReadAllQuery.class));

        // Result type
        query.setHint(QueryHints.QUERY_TYPE, QueryType.Report);
        query.setHint(QueryHints.RESULT_TYPE, ResultType.Map);
        assertTrue("RESULT_TYPE not set.", ((ReportQuery)((JpaQuery)query).getDatabaseQuery()).getReturnType() == ReportQuery.ShouldReturnReportResult);

        query.setHint(QueryHints.RESULT_TYPE, ResultType.Array);
        assertTrue("RESULT_TYPE not set.", ((ReportQuery)((JpaQuery)query).getDatabaseQuery()).getReturnType() == ReportQuery.ShouldReturnArray);

        query.setHint(QueryHints.RESULT_TYPE, ResultType.Value);
        assertTrue("RESULT_TYPE not set.", ((ReportQuery)((JpaQuery)query).getDatabaseQuery()).getReturnType() == ReportQuery.ShouldReturnSingleValue);

        query.setHint(QueryHints.QUERY_TYPE, QueryType.DataRead);
        query.setHint(QueryHints.RESULT_TYPE, ResultType.Map);
        query.setHint(QueryHints.RESULT_TYPE, ResultType.Array);
        query.setHint(QueryHints.RESULT_TYPE, ResultType.Value);

        closeEntityManager(em);
    }

    /**
     * This test ensures that the eclipselink.batch query hint works.
     * It tests two things.
     *
     * 1. That the batch read attribute is properly added to the query
     * 2. That the query will execute
     *
     * It does not do any verification that the batch reading feature actually works.  That is
     * left for the batch reading testing to do.
     */
    public void testBatchQueryHint(){
        int id1 = 0;
        EntityManager em = createEntityManager();
        beginTransaction(em);

        Employee manager = new Employee();
        manager.setFirstName("Marvin");
        manager.setLastName("Malone");
        PhoneNumber number = new PhoneNumber("cell", "613", "888-8888");
        manager.addPhoneNumber(number);
        number = new PhoneNumber("home", "613", "888-8880");
        manager.addPhoneNumber(number);
        em.persist(manager);
        id1 = manager.getId();

        Employee emp = new Employee();
        emp.setFirstName("Melvin");
        emp.setLastName("Malone");
        emp.setManager(manager);
        manager.addManagedEmployee(emp);
        number = new PhoneNumber("cell", "613", "888-9888");
        emp.addPhoneNumber(number);
        number = new PhoneNumber("home", "613", "888-0880");
        emp.addPhoneNumber(number);
        em.persist(emp);

        emp = new Employee();
        emp.setFirstName("David");
        emp.setLastName("Malone");
        emp.setManager(manager);
        manager.addManagedEmployee(emp);
        number = new PhoneNumber("cell", "613", "888-9988");
        emp.addPhoneNumber(number);
        number = new PhoneNumber("home", "613", "888-0980");
        emp.addPhoneNumber(number);
        em.persist(emp);

        em.flush();//use flush and rollback the transaction for test cleanup
        em.clear();

        org.eclipse.persistence.jpa.JpaQuery query = (org.eclipse.persistence.jpa.JpaQuery)em.createQuery("SELECT e FROM Employee e WHERE e.lastName = 'Malone' order by e.firstName");
        query.setHint(QueryHints.BATCH, "e.phoneNumbers");
        query.setHint(QueryHints.BATCH, "e.manager.phoneNumbers");
        query.setHint(QueryHints.BATCH_TYPE, "IN");
        query.setHint(QueryHints.BATCH_SIZE, "10");

        ReadAllQuery raq = (ReadAllQuery)query.getDatabaseQuery();
        List expressions = raq.getBatchReadAttributeExpressions();
        assertTrue(expressions.size() == 2);
        Expression exp = (Expression)expressions.get(0);
        assertTrue(exp.isQueryKeyExpression());
        assertTrue(exp.getName().equals("phoneNumbers"));
        exp = (Expression)expressions.get(1);
        assertTrue(exp.isQueryKeyExpression());
        assertTrue(exp.getName().equals("phoneNumbers"));

        List resultList = query.getResultList();
        emp = (Employee)resultList.get(0);
        emp.getPhoneNumbers().hashCode();

        emp.getManager().getPhoneNumbers().hashCode();

        emp = (Employee)resultList.get(1);
        emp.getPhoneNumbers().hashCode();

        rollbackTransaction(em);
    }

    /**
     * This test ensures that the eclipselink.fetch query hint works.
     * It tests two things.
     *
     * 1. That the joined attribute is properly added to the query
     * 2. That the query will execute
     *
     * It does not do any verification that the joining feature actually works.  That is
     * left for the joining testing to do.
     */
    public void testFetchQueryHint(){
        int id1 = 0;
        EntityManager em = createEntityManager();
        beginTransaction(em);

        try {
            Employee manager = new Employee();
            manager.setFirstName("Marvin");
            manager.setLastName("Malone");
            PhoneNumber number = new PhoneNumber("cell", "613", "888-8888");
            manager.addPhoneNumber(number);
            number = new PhoneNumber("home", "613", "888-8880");
            manager.addPhoneNumber(number);
            em.persist(manager);
            id1 = manager.getId();

            Employee emp = new Employee();
            emp.setFirstName("Melvin");
            emp.setLastName("Malone");
            emp.setManager(manager);
            manager.addManagedEmployee(emp);
            number = new PhoneNumber("cell", "613", "888-9888");
            emp.addPhoneNumber(number);
            number = new PhoneNumber("home", "613", "888-0880");
            emp.addPhoneNumber(number);
            em.persist(emp);

            emp = new Employee();
            emp.setFirstName("David");
            emp.setLastName("Malone");
            emp.setManager(manager);
            manager.addManagedEmployee(emp);
            number = new PhoneNumber("cell", "613", "888-9988");
            emp.addPhoneNumber(number);
            number = new PhoneNumber("home", "613", "888-0980");
            emp.addPhoneNumber(number);
            em.persist(emp);

            em.flush();
            em.clear();

            org.eclipse.persistence.jpa.JpaQuery query = (org.eclipse.persistence.jpa.JpaQuery)em.createQuery("SELECT e FROM Employee e WHERE e.lastName = 'Malone' order by e.firstName");
            query.setHint(QueryHints.LEFT_FETCH, "e.manager");
            ReadAllQuery raq = (ReadAllQuery)query.getDatabaseQuery();
            List expressions = raq.getJoinedAttributeExpressions();
            assertTrue(expressions.size() == 1);
            Expression exp = (Expression)expressions.get(0);
            assertTrue(exp.getName().equals("manager"));
            query.setHint(QueryHints.FETCH, "e.manager.phoneNumbers");
            assertTrue(expressions.size() == 2);

            List resultList = query.getResultList();
            emp = (Employee)resultList.get(0);
        } finally {
            rollbackTransaction(em);
        }
    }

    // Bug 366458 - Query hint eclipselink.join-fetch can cause wrongly populated data
    public void testNestedFetchQueryHints() {
        EntityManager em= createEntityManager();
        String errorMsg = "";

        if (isJTA()) {
            beginTransaction(em);
        }

        try {
            Query query1 = em.createQuery("SELECT e FROM Employee e");
            query1.setHint(QueryHints.FETCH, "e.manager");
            query1.setHint(QueryHints.FETCH, "e.manager.projects");
            query1.setHint(QueryHints.FETCH, "e.manager.projects.teamMembers");
            query1.setHint(QueryHints.FETCH, "e.manager.projects.teamMembers.dealers");
            query1.setHint(QueryHints.FETCH, "e.manager.projects.teamMembers.phoneNumbers");
            query1.getResultList();
            errorMsg += verifyJoinAttributeExpressions("query1", query1);

            Query query2 = em.createQuery("SELECT e FROM Employee e");
            query2.setHint(QueryHints.FETCH, "e.manager.projects.teamMembers");
            query2.setHint(QueryHints.FETCH, "e.manager.projects.teamMembers.dealers");
            query2.setHint(QueryHints.FETCH, "e.manager.projects.teamMembers.phoneNumbers");
            query2.getResultList();
            errorMsg += verifyJoinAttributeExpressions("query2", query2);

            Query query3 = em.createQuery("SELECT e FROM Employee e");
            query3.setHint(QueryHints.FETCH, "e.manager.projects.teamMembers.dealers");
            query3.setHint(QueryHints.FETCH, "e.manager.projects.teamMembers.phoneNumbers");
            query3.getResultList();
            errorMsg += verifyJoinAttributeExpressions("query3", query3);

            Query query4 = em.createQuery("SELECT e FROM Employee e");
            query4.setHint(QueryHints.LEFT_FETCH, "e.manager");
            query4.setHint(QueryHints.LEFT_FETCH, "e.manager.projects");
            query4.setHint(QueryHints.LEFT_FETCH, "e.manager.projects.teamMembers");
            query4.setHint(QueryHints.LEFT_FETCH, "e.manager.projects.teamMembers.dealers");
            query4.setHint(QueryHints.LEFT_FETCH, "e.manager.projects.teamMembers.phoneNumbers");
            query4.getResultList();
            errorMsg += verifyJoinAttributeExpressions("query4", query4);

            Query query5 = em.createQuery("SELECT e FROM Employee e");
            query5.setHint(QueryHints.LEFT_FETCH, "e.manager.projects.teamMembers");
            query5.setHint(QueryHints.LEFT_FETCH, "e.manager.projects.teamMembers.dealers");
            query5.setHint(QueryHints.LEFT_FETCH, "e.manager.projects.teamMembers.phoneNumbers");
            query5.getResultList();
            errorMsg += verifyJoinAttributeExpressions("query5", query5);

            Query query6 = em.createQuery("SELECT e FROM Employee e");
            query6.setHint(QueryHints.LEFT_FETCH, "e.manager.projects.teamMembers.dealers");
            query6.setHint(QueryHints.LEFT_FETCH, "e.manager.projects.teamMembers.phoneNumbers");
            query6.getResultList();
            errorMsg += verifyJoinAttributeExpressions("query6", query6);
        } finally {
            if (isTransactionActive(em)) {
                rollbackTransaction(em);
            }
            closeEntityManager(em);
        }

        if (errorMsg.length() > 0) {
            fail(errorMsg);
        }
    }
    protected String verifyJoinAttributeExpressions(String queryName, Query query) {
        String[] names = {"manager", "projects", "teamMembers", "dealers", "phoneNumbers"};
        ReadAllQuery  readAllQuery = query.unwrap(ReadAllQuery.class);
        List<Expression> joinExpressions = readAllQuery.getJoinedAttributeManager().getJoinedAttributeExpressions();
        boolean ok = true;
        if (joinExpressions.size() != names.length) {
            ok = false;
        } else {
            Expression baseExp = readAllQuery.getExpressionBuilder();
            for (int i=0; i <= names.length - 1 && ok; i++) {
                QueryKeyExpression exp = (QueryKeyExpression)joinExpressions.get(i);
                if (baseExp != exp.getBaseExpression()) {
                    ok = false;
                }
                if (!exp.getName().equals(names[i])) {
                    // "dealers" and "phoneNumbers" may have been transposed in the list
                    if (i == names.length - 2) {
                        names[names.length - 2] = "phoneNumbers";
                        names[names.length - 1] = "dealers";
                        if (!exp.getName().equals(names[i])) {
                            ok = false;
                        }
                    } else {
                        ok = false;
                    }
                }
                // "dealers" and "phoneNumbers" have the same base
                if (i <= 2) {
                    baseExp = exp;
                }
            }
        }
        String errorMsg = "";
        if (!ok) {
            errorMsg = queryName + ":\n" + joinExpressions + "\n";
        }
        return errorMsg;
    }

    public void testNestedBatchQueryHints() {
        String errorMsg = "";
        clearCache();
        ServerSession session = getServerSession();
        QuerySQLTracker counter = new QuerySQLTracker(session);
        EntityManager em= createEntityManager();
        beginTransaction(em);
        try {
            // setup
            int nEmployees = 2;
            int nProjects = 2;
            int nTeamMembers = 2;
            int nDealers = 2;
            int nPhones = 2;
            boolean useLargeProject = false;
            List<Employee> employees = new ArrayList(nEmployees);
            List<Employee> teamMembers = new ArrayList(nEmployees*nProjects*nTeamMembers);
            for (int i = 0; i < nEmployees; i++) {
                String iStr = Integer.toString(i);
                Employee emp = new Employee("Employee_NestedBatchQueryHint", iStr);
                employees.add(emp);
                Employee manager = new Employee("Manager_NestedBatchQueryHint", iStr);
                manager.addManagedEmployee(emp);
                for (int j = 0; j < nProjects; j++) {
                    String jStr = Integer.toString(j);
                    Project project;
                    if (useLargeProject) {
                        project = new LargeProject();
                    } else {
                        project = new SmallProject();
                    }
                    useLargeProject = !useLargeProject;
                    project.setName(iStr + jStr);
                    manager.addProject(project);
                    project.addTeamMember(manager);
                    for (int k = 0; k < nTeamMembers; k++) {
                        String kStr = Integer.toString(k);
                        String teamMemberLastName = iStr+jStr+kStr;
                        Employee teamMember = new Employee("TeamMember_NestedBatchQueryHint", teamMemberLastName);
                        teamMembers.add(teamMember);
                        teamMember.addProject(project);
                        project.addTeamMember(teamMember);
                        for (int l = 0; l < nDealers; l++) {
                            String lStr = Integer.toString(l);
                            Dealer dealer = new Dealer(lStr, teamMemberLastName);
                            teamMember.addDealer(dealer);
                        }
                        for (int l = 0; l < nPhones; l++) {
                            String lStr = Integer.toString(l);
                            PhoneNumber phone = new PhoneNumber(lStr, teamMemberLastName, lStr+lStr+lStr+lStr+lStr+lStr+lStr);
                            teamMember.addPhoneNumber(phone);
                        }
                    }
                }
            }
            // Persist cacscaded manager, then projects
            for (Employee emp : employees) {
                em.persist(emp);
            }
            // Persist cacscaded dealers and phones
            for (Employee emp : teamMembers) {
                em.persist(emp);
            }
            em.flush();

            // test
            em.clear();
            Query query1 = em.createQuery("SELECT e FROM Employee e WHERE e.firstName = 'Employee_NestedBatchQueryHint' ORDER BY e.lastName");
            query1.setHint(QueryHints.BATCH, "e.manager");
            query1.setHint(QueryHints.BATCH, "e.manager.projects");
            query1.setHint(QueryHints.BATCH, "e.manager.projects.teamMembers");
            query1.setHint(QueryHints.BATCH, "e.manager.projects.teamMembers.dealers");
            query1.setHint(QueryHints.BATCH, "e.manager.projects.teamMembers.phoneNumbers");
            errorMsg += verifyBatchReading("query1", query1, counter, employees, session);

            em.clear();
            Query query2 = em.createQuery("SELECT e FROM Employee e WHERE e.firstName = 'Employee_NestedBatchQueryHint' ORDER BY e.lastName");
            query2.setHint(QueryHints.BATCH, "e.manager.projects.teamMembers");
            query2.setHint(QueryHints.BATCH, "e.manager.projects.teamMembers.dealers");
            query2.setHint(QueryHints.BATCH, "e.manager.projects.teamMembers.phoneNumbers");
            errorMsg += verifyBatchReading("query2", query2, counter, employees, session);

            em.clear();
            Query query3 = em.createQuery("SELECT e FROM Employee e WHERE e.firstName = 'Employee_NestedBatchQueryHint' ORDER BY e.lastName");
            query3.setHint(QueryHints.BATCH, "e.manager.projects.teamMembers.dealers");
            query3.setHint(QueryHints.BATCH, "e.manager.projects.teamMembers.phoneNumbers");
            errorMsg += verifyBatchReading("query3", query3, counter, employees, session);

        } finally {
            // clean-up
            rollbackTransaction(em);
            closeEntityManager(em);
            counter.remove();
        }
        if (errorMsg.length() > 0) {
            fail(errorMsg);
        }
    }
    protected String verifyBatchReading(String queryName, Query query, QuerySQLTracker counter, List<Employee> originalEmployees, ServerSession session) {
        List<Employee> employees = query.getResultList();
        Employee employee = employees.get(0);
        Project project = employee.getManager().getProjects().iterator().next();
        Employee teamMember = null;
        for (Employee currentTeamMember : (Collection<Employee>)project.getTeamMembers()) {
            if (currentTeamMember.getFirstName().equals("TeamMember_NestedBatchQueryHint")) {
                teamMember = currentTeamMember;
                break;
            }
        }
        teamMember.getDealers().size();
        teamMember.getPhoneNumbers().size();

        // References have been triggered on a single object,
        // batch reading should have caused all the objects to be read,
        // therefore triggering all remaining relations should produce no sql.
        counter.getSqlStatements().clear();
        for (Employee emp : employees) {
            Employee manager = emp.getManager();
            for (Project proj : manager.getProjects()) {
                for (Employee currentTeamMember : (Collection<Employee>)proj.getTeamMembers()) {
                    if (currentTeamMember != manager) {
                        currentTeamMember.getDealers().size();
                        currentTeamMember.getPhoneNumbers().size();
                    }
                }
            }
        }

        String errorMsg = "";
        if (counter.getSqlStatements().size() > 0) {
            errorMsg = counter.getSqlStatements() + "\n";
        }

        if (employees.size() != originalEmployees.size()) {
            errorMsg += "employees.size() = " + employees.size() + "; originalEmployees.size() = " + originalEmployees.size() + "\n";
        } else {
            // order of read employees should be the same bacause it's ordered by last name.
            for (int i = 0; i < employees.size(); i++) {
                if (!session.compareObjects(originalEmployees.get(i), employees.get(i))) {
                    errorMsg += "Original and read employee are not equal: original = " + originalEmployees.get(i).getLastName() + "; read = " + employees.get(i).getLastName() + "\n";
                }
                if (!session.compareObjects(originalEmployees.get(i).getManager(), employees.get(i).getManager())) {
                    errorMsg += "Original and read employee.getManager() are not equal: original = " + originalEmployees.get(i).getManager().getLastName() + "; read = " + employees.get(i).getManager().getLastName() + "\n";
                }
                Collection<Project> projects = employees.get(i).getManager().getProjects();
                Collection<Project> originalProjects = originalEmployees.get(i).getManager().getProjects();
                for (Project originalProj : originalProjects) {
                    boolean foundEqualName = false;
                    for (Project proj : projects) {
                        if (originalProj.getName().equals(proj.getName())) {
                            foundEqualName = true;
                            if (!session.compareObjects(originalProj, proj)) {
                                errorMsg += "Original and read projects are not equal for name: " + originalProj.getName() + "\n";
                            }
                            break;
                        }
                    }
                    if (!foundEqualName) {
                        errorMsg += "No read project has name " + originalProj.getName() + "\n";
                    }
                }
            }
        }

        if (errorMsg.length() > 0) {
            errorMsg = queryName + ":\n" + errorMsg;
        }
        return errorMsg;
    }

    /**
     * Test that the proper exception is thrown when an incorrect batch or fetch query hint is set on the queyr.
     */
    public void testIncorrectBatchQueryHint(){
        EntityManager em = createEntityManager();
        QueryException exception = null;
        try{
            Query query = em.createQuery("SELECT e FROM Employee e WHERE e.lastName = 'Malone' order by e.firstName");
            query.setHint(QueryHints.BATCH, "e");
            query.getResultList();
        } catch (QueryException exc){
            exception = exc;
        }
        assertNotNull("No exception was thrown on an incorrect BATCH query hint.", exception);
        assertTrue("Incorrect Exception thrown", exception.getErrorCode() == QueryException.QUERY_HINT_DID_NOT_CONTAIN_ENOUGH_TOKENS);
        exception = null;
        try{
            Query query = em.createQuery("SELECT e FROM Employee e WHERE e.lastName = 'Malone' order by e.firstName");
            query.setHint(QueryHints.BATCH, "e.abcdef");
            query.getResultList();
        } catch (QueryException exc){
            exception = exc;
        }
        assertNotNull("No exception was thrown on an incorrect BATCH query hint.", exception);
        assertTrue("Incorrect Exception thrown", exception.getErrorCode() == QueryException.QUERY_HINT_NAVIGATED_NON_EXISTANT_RELATIONSHIP);

        exception = null;
        try{
            Query query = em.createQuery("SELECT e FROM Employee e WHERE e.lastName = 'Malone' order by e.firstName");
            query.setHint(QueryHints.BATCH, "e.firstName");
            query.getResultList();
        } catch (QueryException exc){
            exception = exc;
        }
        assertNotNull("No exception was thrown when an incorrect relationship was navigated in a BATCH query hint.", exception);
        assertTrue("Incorrect Exception thrown", exception.getErrorCode() == QueryException.QUERY_HINT_NAVIGATED_ILLEGAL_RELATIONSHIP);

        exception = null;
        try{
            Query query = em.createQuery("SELECT e FROM Employee e WHERE e.lastName = 'Malone' order by e.firstName");
            query.setHint(QueryHints.FETCH, "e");
            query.getResultList();
        } catch (QueryException exc){
            exception = exc;
        }
        assertNotNull("No exception was thrown on an incorrect FETCH query hint.", exception);
        assertTrue("Incorrect Exception thrown", exception.getErrorCode() == QueryException.QUERY_HINT_DID_NOT_CONTAIN_ENOUGH_TOKENS);

        exception = null;
        try{
            Query query = em.createQuery("SELECT e FROM Employee e WHERE e.lastName = 'Malone' order by e.firstName");
            query.setHint(QueryHints.FETCH, "e.abcdef");
            query.getResultList();
        } catch (QueryException exc){
            exception = exc;
        }
        assertNotNull("No exception was thrown on an incorrect FETCH query hint.", exception);
        assertTrue("Incorrect Exception thrown", exception.getErrorCode() == QueryException.QUERY_HINT_NAVIGATED_NON_EXISTANT_RELATIONSHIP);

        exception = null;
        try{
            Query query = em.createQuery("SELECT e FROM Employee e WHERE e.lastName = 'Malone' order by e.firstName");
            query.setHint(QueryHints.FETCH, "e.firstName");
            query.getResultList();
        } catch (QueryException exc){
            exception = exc;
        }
        assertNotNull("No exception was thrown when an incorrect relationship was navigated in a FETCH query hint.", exception);
        assertTrue("Incorrect Exception thrown", exception.getErrorCode() == QueryException.QUERY_HINT_NAVIGATED_ILLEGAL_RELATIONSHIP);

    }

    /*
     * Bug51411440: need to throw IllegalStateException if query executed on closed em
     */
    public void testQueryOnClosedEM() {
        // Server entity managers are not closed.
        if (isOnServer()) {
            return;
        }
        boolean exceptionWasThrown = false;
        EntityManager em = createEntityManager();
        Query q =  em.createQuery("SELECT e FROM Employee e ");
        closeEntityManager(em);
        if(em.isOpen()) {
            fail("Closed EntityManager is still open");
        }
        try{
            q.getResultList();
        }catch(java.lang.IllegalStateException e){
            exceptionWasThrown=true;
        }
        if (!exceptionWasThrown){
            fail("Query on Closed EntityManager did not throw an exception");
        }
    }

    public void testNullifyAddressIn() {
        if ((JUnitTestCase.getServerSession()).getPlatform().isSymfoware()) {
            getServerSession().logMessage("Test testNullifyAddressIn skipped for this platform, " +
                     "Symfoware doesn't support UpdateAll/DeleteAll on multi-table objects (see rfe 298193).");
            return;
        }
        EntityManager em = createEntityManager();
        beginTransaction(em);
        try {
            em.createQuery("UPDATE Employee e SET e.address = null WHERE e.address.country IN ('Canada', 'US')").executeUpdate();
        } finally {
            rollbackTransaction(em);
            closeEntityManager(em);
        }
    }

    //test for bug 5234283: WRONG =* SQL FOR LEFT JOIN ON DERBY AND DB2 PLATFORMS
    public void testLeftJoinOneToOneQuery() {
        EntityManager em = createEntityManager();
        List results = em.createQuery("SELECT a FROM Employee e LEFT JOIN e.address a").getResultList();
        results.toString();
        closeEntityManager(em);
    }

    // Test multiple items from a report query. Will verify the version on
    // only one of the results.
    public void testLockingLeftJoinOneToOneQuery() {
        // Grab a copy of the results that we will lock then verify.
        List<Object[]> results = createEntityManager().createQuery("SELECT m, e FROM Employee e LEFT JOIN e.manager m").getResultList();

        if (! results.isEmpty()) {
            // Issuing the force increment locking query.
            EntityManager em = createEntityManager();
            beginTransaction(em);
            em.createQuery("SELECT m, e FROM Employee e LEFT JOIN e.manager m").setLockMode(LockModeType.OPTIMISTIC_FORCE_INCREMENT).getResultList();
            commitTransaction(em);

            // Verify the items of the result list all had a version increment.
            beginTransaction(em);
            try{
                for (Object[] result : results) {
                    Employee managerBefore = (Employee) result[0];
                    if (managerBefore != null) {
                        int managerVersionBefore = managerBefore.getVersion();
                        Employee managerAfter = em.find(Employee.class, managerBefore.getId());
                        int managerVersionAfter = managerAfter.getVersion();
                        assertTrue("The manager version was not updated on the locking query.", (managerVersionAfter - managerVersionBefore) == 1);
                    }

                    Employee employeeBefore = (Employee) result[1];
                    if (employeeBefore != null) {
                        int employeeVersionBefore = employeeBefore.getVersion();
                        Employee employeeAfter = em.find(Employee.class, employeeBefore.getId());
                        int employeeVersionAfter = employeeAfter.getVersion();
                        assertTrue("The employee version was not updated on the locking query.", (employeeVersionAfter - employeeVersionBefore) == 1);
                    }
                }
            } finally {
               if(this.isTransactionActive(em)) {
                   rollbackTransaction(em);
                  }
                   closeEntityManager(em);
            }
        }
    }

    // Test single item from a report query.
    public void testLockingLeftJoinOneToOneQuery2() {
        // Grab a copy of the results that we will lock then verify.
        List<Address> results = createEntityManager().createQuery("SELECT a FROM Employee e LEFT JOIN e.address a").getResultList();

        if (results != null) {
            // Issuing the force increment locking query.
            EntityManager em = createEntityManager();
            beginTransaction(em);
            em.createQuery("SELECT a FROM Employee e LEFT JOIN e.address a").setLockMode(LockModeType.OPTIMISTIC_FORCE_INCREMENT).getResultList();
            commitTransaction(em);

            // Verify the items of the result list all had a version increment.
            beginTransaction(em);
            try{
                for (Address address : results) {
                    if (address != null) {
                        int versionBefore = address.getVersion();
                        Address addressAfter = em.find(Address.class, address.getID());
                        int versionAfter = addressAfter.getVersion();
                        assertTrue("The version on an address was not updated on the locking query.", (versionAfter - versionBefore) == 1);
                    }
                }
            } finally {
               if(this.isTransactionActive(em)) {
                   rollbackTransaction(em);
                  }
                   closeEntityManager(em);
            }
        }
    }

    // Test the clone method works correctly with lazy attributes.
    public void testCloneable() {
        EntityManager em = createEntityManager();
        beginTransaction(em);

        Employee employee = new Employee();
        employee.setFirstName("Owen");
        employee.setLastName("Hargreaves");
        employee.getAddress();
        Employee clone = employee.clone();

        Address address = new Address();
        address.setCity("Munich");
        clone.setAddress(address);
        clone.getAddress();
        em.persist(clone);
        if (employee.getAddress() == clone.getAddress()) {
            fail("Changing clone address changed original.");
        }
        commitTransaction(em);
        clearCache();
        closeEntityManager(em);
        em = createEntityManager();
        beginTransaction(em);
        employee = em.find(Employee.class, clone.getId());
        clone = employee.clone();

        address = new Address();
        address.setCity("Not Munich");
        clone.setAddress(address);
        clone.getAddress();
        if (employee.getAddress() == clone.getAddress()) {
            fail("Changing clone address changed original.");
        }
        if (employee.getAddress() == null) {
            fail("Changing clone address reset original to null.");
        }
        if (clone.getAddress() != address) {
            fail("Changing clone did not work.");
        }
        commitTransaction(em);
        closeEntityManager(em);

        em = createEntityManager();
        beginTransaction(em);
        employee = em.find(Employee.class, clone.getId());
        clone = employee.clone();
        clone.setId(null);
        em.persist(clone);
        commitTransaction(em);
        if (clone.getId() == null) {
            fail("Clone was not persisted.");
        }
        beginTransaction(em);
        employee = em.find(Employee.class, clone.getId());
        em.remove(employee);
        commitTransaction(em);
        closeEntityManager(em);
    }

    // test for GlassFish bug 711 - throw a descriptive exception when an uninstantiated valueholder is serialized and then accessed
    public void testSerializedLazy(){
        EntityManager em = createEntityManager();

        beginTransaction(em);

        Employee emp = new Employee();
        emp.setFirstName("Owen");
        emp.setLastName("Hargreaves");
        emp.setId(40);
        Address address = new Address();
        address.setCity("Munich");
        emp.setAddress(address);
        em.persist(emp);
        em.flush();
        commitTransaction(em);
        closeEntityManager(em);
        clearCache();
        em = createEntityManager();
        String ejbqlString = "SELECT e FROM Employee e WHERE e.firstName = 'Owen' and e.lastName = 'Hargreaves'";
        List result = em.createQuery(ejbqlString).getResultList();
        emp = (Employee)result.get(0);
        Exception exception = null;
        try {
            ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
            ObjectOutputStream stream = new ObjectOutputStream(byteStream);

            stream.writeObject(emp);
            stream.flush();
            byte arr[] = byteStream.toByteArray();
            ByteArrayInputStream inByteStream = new ByteArrayInputStream(arr);
            ObjectInputStream inObjStream = new ObjectInputStream(inByteStream);

            emp = (Employee) inObjStream.readObject();
            emp.getAddress();
        } catch (ValidationException e) {
            if (e.getErrorCode() == ValidationException.INSTANTIATING_VALUEHOLDER_WITH_NULL_SESSION){
                exception = e;
            } else {
                fail("An unexpected exception was thrown while testing serialization of ValueHolders: " + e.toString());
            }
        } catch (Exception e){
            fail("An unexpected exception was thrown while testing serialization of ValueHolders: " + e.toString());
        }

        // Only throw error if weaving was used.
        if (isWeavingEnabled()) {
            assertNotNull("The correct exception was not thrown while traversing an uninstantiated lazy relationship on a serialized object: " + exception, exception);
        }
        beginTransaction(em);
        emp = em.find(Employee.class, emp.getId());
        em.remove(emp);
        commitTransaction(em);
    }

    //test for bug 5170395: GET THE SEQUENCING EXCEPTION WHEN RUNNING FOR THE FIRST TIME ON A CLEAR SCHEMA
    public void testSequenceObjectDefinition() {
        EntityManager em = createEntityManager();
        ServerSession ss = getServerSession();
        if(!ss.getLogin().getPlatform().supportsSequenceObjects() || isOnServer()) {
            // platform that supports sequence objects is required for this test
            // this test not work on server since the bug: 262251
            closeEntityManager(em);
            return;
        }
        String seqName = "testSequenceObjectDefinition";
        try {
            // first param is preallocationSize, second is startValue
            // both should be positive
            internalTestSequenceObjectDefinition(10, 1, seqName, em, ss);
            internalTestSequenceObjectDefinition(10, 5, seqName + "1", em, ss);
            internalTestSequenceObjectDefinition(10, 15, seqName + "2", em, ss);
        } finally {
            closeEntityManager(em);
        }
    }

    protected void internalTestSequenceObjectDefinition(int preallocationSize, int startValue, String seqName, EntityManager em, ServerSession ss) {
        NativeSequence sequence = new NativeSequence(seqName, preallocationSize, startValue, false);
        sequence.onConnect(ss.getPlatform());
        SequenceObjectDefinition def = new SequenceObjectDefinition(sequence);
        try {
            // create sequence
            String createStr = def.buildCreationWriter(ss, new StringWriter()).toString();
            beginTransaction(em);
            Query query = em.createNativeQuery(createStr);
            query.setHint(QueryHints.BATCH_WRITING, false);
            query.executeUpdate();
            commitTransaction(em);

            // sequence value preallocated
            Vector seqValues = sequence.getGeneratedVector(null, ss);
            int firstSequenceValue = ((Number)seqValues.elementAt(0)).intValue();
            if(firstSequenceValue != startValue) {
                fail(seqName + " sequence with preallocationSize = "+preallocationSize+" and startValue = " + startValue + " produced wrong firstSequenceValue =" + firstSequenceValue);
            }
        } finally {
            if (isTransactionActive(em)) {
                rollbackTransaction(em);
            }
            sequence.onDisconnect(ss.getPlatform());
            // Symfoware doesn't allow drop while connections that performed
            // CREATE and DML on the sequence are still open.
            if (JUnitTestCase.getServerSession().getPlatform().isSymfoware()) return;
            // drop sequence
            String dropStr = def.buildDeletionWriter(ss, new StringWriter()).toString();
            beginTransaction(em);
            Query query = em.createNativeQuery(dropStr);
            query.setHint(QueryHints.BATCH_WRITING, false);
            query.executeUpdate();
            commitTransaction(em);
        }
    }

    public void testMergeDetachedObject() {
        // Step 1 - read a department and clear the cache.
        clearCache();
        EntityManager em = createEntityManager();
        Query query = em.createNamedQuery("findAllSQLDepartments");
        Collection departments = query.getResultList();

        Department detachedDepartment;

        // This test seems to get called twice. Once with departments populated
        // and a second time with the department table empty.
        if (departments.isEmpty()) {
            beginTransaction(em);
            detachedDepartment = new Department();
            detachedDepartment.setName("Department X");
            em.persist(detachedDepartment);
            commitTransaction(em);
        } else {
            detachedDepartment = (Department) departments.iterator().next();
        }

        closeEntityManager(em);
        clearCache();

        // Step 2 - create a new em, create a new employee with the
        // detached department and then query the departments again.
        em = createEntityManager();
        beginTransaction(em);

        Employee emp = new Employee();
        emp.setFirstName("Crazy");
        emp.setLastName("Kid");
        emp.setId(41);
        emp.setDepartment(detachedDepartment);

        em.persist(emp);
        commitTransaction(em);

        try {
            em.createNamedQuery("findAllSQLDepartments").getResultList();
        } catch (NullPointerException e) {
            assertTrue("The detached department caused a null pointer on the query execution.", false);
        }

        closeEntityManager(em);
    }

    //bug gf830 - attempting to merge a removed entity should throw an IllegalArgumentException
    public void testMergeRemovedObject() {
        //create an Employee
        Employee emp = new Employee();
        emp.setFirstName("testMergeRemovedObjectEmployee");
        emp.setId(42);

        //persist the Employee
        EntityManager em = createEntityManager();
        try{
            beginTransaction(em);
            em.persist(emp);
            commitTransaction(em);
        }catch (RuntimeException re){
            if (isTransactionActive(em)){
                rollbackTransaction(em);
            }
            throw re;
        }

        beginTransaction(em);
        em.remove(em.find(Employee.class, emp.getId())); //attempt to remove the Employee
        try{
            em.merge(emp);    //then attempt to merge the Employee
            fail("No exception thrown when merging a removed entity is attempted.");
        }catch (IllegalArgumentException iae){
            //expected
        }catch (Exception e) {
            fail("Wrong exception type thrown: " + e.getClass());
        }finally {
            rollbackTransaction(em);

            //clean up - ensure removal of employee
            beginTransaction(em);
            em.remove(em.find(Employee.class, emp.getId()));
            commitTransaction(em);
            closeEntityManager(em);
        }
    }

    //detach(object) on a removed object does not throw exception. This test only
    //checks whether an removed object is completely deleted from the
    //getDeletedObject()Map after 'detach(removedobject)' is invoked
    public void testDetachRemovedObject() {
        //create an Employee
        Employee emp = new Employee();
        emp.setFirstName("testDetachRemovedObjectEmployee");

        //persist the Employee
        EntityManager em = createEntityManager();
        try {
            beginTransaction(em);
            em.persist(emp);
            commitTransaction(em);
        } catch (RuntimeException re){
            if (isTransactionActive(em)){
                rollbackTransaction(em);
            }
            throw re;
        }

        beginTransaction(em);
        em.remove(em.find(Employee.class, emp.getId())); //attempt to remove the Employee
        commitTransaction(em);
        beginTransaction(em);
        EntityManagerImpl em1 = (EntityManagerImpl)em.getDelegate();
        try {
            em.detach(emp);    //attempt to detach the Employee
            UnitOfWork uow = em1.getUnitOfWork();
            UnitOfWorkImpl uowImpl = (UnitOfWorkImpl)uow;
            boolean afterClear = uowImpl.getDeletedObjects().containsKey(emp);
            assertFalse("exception thrown when detaching a removed entity is attempted.", afterClear);
        } catch (IllegalArgumentException iae){
            return;
        } finally {
            if (isTransactionActive(em)){
                rollbackTransaction(em);
            }
            closeEntityManager(em);
        }
    }

    //bug6167431: tests calling merge on a new object puts it in the cache, and that all new objects in the tree get IDs generated
    public void testMergeNewObject() {
        //create an Employee
        Employee emp = new Employee();
        emp.setFirstName("testMergeNewObjectEmployee");
        emp.setAddress(new Address("45 O'Connor", "Ottawa", "Ont", "Canada", "K1P1A4"));

        //persist the Employee
        EntityManager em = createEntityManager();
        try{
            beginTransaction(em);
            Employee managedEmp = em.merge(emp);
            assertNotNull("merged Employee doesn't have its ID generated", managedEmp.getId());
            assertNotNull("merged Employee cannot be found using find", em.find(Employee.class, managedEmp.getId()));
            //this won't work till bug:6193761 is fixed
            //this.assertTrue("referenced Address doesn't have its ID generated", managedEmp.getAddress().getId()!=0);
        }finally {
            if (isTransactionActive(em)){
                rollbackTransaction(em);
            }
        }

    }

    //bug6180972: Tests calling merge on a new Entity that uses int as its ID, verifying it is set and cached correctly
    public void testMergeNewObject2() {
        //create an Equipment
        Equipment equip = new Equipment();
        equip.setDescription("New Equipment");

        EntityManager em = createEntityManager();
        try{
            beginTransaction(em);
            Equipment managedEquip = em.merge(equip);

            assertTrue("merged Equipment doesn't have its ID generated", managedEquip.getId()!=0);
            assertNotNull("merged Equipment cannot be found using find", em.find(Equipment.class, managedEquip.getId()));
        }finally {
            if (isTransactionActive(em)){
                rollbackTransaction(em);
            }
        }
    }

    //bug6342382: NEW OBJECT MERGE THROWS OPTIMISTICLOCKEXCEPTION
    public void testMergeNewObject3_UseSequencing() {
        internalTestMergeNewObject3(true);
    }

    //bug6342382: NEW OBJECT MERGE THROWS OPTIMISTICLOCKEXCEPTION
    public void testMergeNewObject3_DontUseSequencing() {
        internalTestMergeNewObject3(false);
    }

    // shouldUseSequencing == false indicates that PKs should be explicitly assigned to the objects
    // rather than generated by sequencing.
    protected void internalTestMergeNewObject3(boolean shouldUseSequencing) {
        int id = 0;
        if(!shouldUseSequencing) {
            // obtain the last used sequence number
            Employee emp = new Employee();
            EntityManager em = createEntityManager();
            beginTransaction(em);
            em.persist(emp);
            commitTransaction(em);
            id = emp.getId();
            beginTransaction(em);
            emp = em.find(Employee.class, emp.getId());
            em.remove(emp);
            commitTransaction(em);
            closeEntityManager(em);
        }

        //create two Employees:
        String firstName = "testMergeNewObjectEmployee3";
        Employee manager = new Employee();
        manager.setFirstName(firstName);
        manager.setLastName("Manager");
        if(!shouldUseSequencing) {
            manager.setId(id++);
        }
        Employee employee = new Employee();
        employee.setFirstName(firstName);
        employee.setLastName("Employee");
        if(!shouldUseSequencing) {
            employee.setId(id++);
        }
        manager.addManagedEmployee(employee);

        //persist the Employee
        EntityManager em = createEntityManager();
        try {
            beginTransaction(em);
            Employee managedEmp = em.merge(manager);
            managedEmp.toString();
        } finally {
            if (isTransactionActive(em)){
                rollbackTransaction(em);
            }
            closeEntityManager(em);
        }
    }

    //merge(null) should throw IllegalArgumentException
    public void testMergeNull(){
        EntityManager em = createEntityManager();
        beginTransaction(em);
        try {
            em.merge(null);
        }catch (IllegalArgumentException iae){
            return;
        }catch (Exception e) {
            fail("Wrong exception type thrown: " + e.getClass());
        }finally {
            rollbackTransaction(em);
            closeEntityManager(em);
        }
        fail("No exception thrown when entityManager.merge(null) attempted.");
    }

    //persist(null) should throw IllegalArgumentException
    public void testPersistNull(){
        EntityManager em = createEntityManager();
        beginTransaction(em);
        try {
            em.persist(null);
        }catch (IllegalArgumentException iae){
            return;
        }catch (Exception e) {
            fail("Wrong exception type thrown: " + e.getClass());
        }finally {
            rollbackTransaction(em);
            closeEntityManager(em);
        }
        fail("No exception thrown when entityManager.persist(null) attempted.");
    }

    //contains(null) should throw IllegalArgumentException
    public void testContainsNull(){
        EntityManager em = createEntityManager();
        beginTransaction(em);
        try {
            em.contains(null);
        }catch (IllegalArgumentException iae){
            return;
        }catch (Exception e) {
            fail("Wrong exception type thrown: " + e.getClass());
        }finally {
            rollbackTransaction(em);
            closeEntityManager(em);
        }
        fail("No exception thrown when entityManager.contains(null) attempted.");
    }

    //detach(null) should throw IllegalArgumentException
    public void testDetachNull() {
        EntityManager em = createEntityManager();
        beginTransaction(em);
        try {
            em.detach(null);
        } catch (IllegalArgumentException iae) {
            return;
        } catch (Exception e) {
            fail("Wrong exception type thrown: " + e.getClass());
        } finally {
            rollbackTransaction(em);
            closeEntityManager(em);
        }
        fail("No exception thrown when entityManager.detach(null) attempted.");
    }

    //bug gf732 - removing null entity should throw an IllegalArgumentException
    public void testRemoveNull(){
        EntityManager em = createEntityManager();
        beginTransaction(em);
        try {
            em.remove(null);
        }catch (IllegalArgumentException iae){
            return;
        }catch (Exception e) {
            fail("Wrong exception type thrown: " + e.getClass());
        }finally {
            rollbackTransaction(em);
            closeEntityManager(em);
        }
        fail("No exception thrown when entityManager.remove(null) attempted.");
    }

    /**
     * GlassFish Bug854, originally calling with null caused a null-pointer exception.
     */
    public void testCreateEntityManagerFactory() {
        if (isOnServer() && isWeavingEnabled()) {
            // Bug 297628 - jpa.advanced.EntityManagerJUnitTestSuite.testCreateEntityManagerFactory failed on WLS for only dynamic weaving
            // Dynamic weaving for Persistence.createEntityManagerFactory can't be done on app. server.
            return;
        }
        EntityManagerFactory factory = null;

        try {
            // First call with correct properties, to ensure test does not corrupt factory.
            Persistence.createEntityManagerFactory("default", JUnitTestCaseHelper.getDatabaseProperties());
            factory = Persistence.createEntityManagerFactory("default", null);
            factory = Persistence.createEntityManagerFactory("default");
        } finally {
            if (factory != null) {
                factory.close();
            }
        }
    }

    //GlassFish Bug854  PU name doesn't exist or PU with the wrong name
    public void testCreateEntityManagerFactory2() {
        if (getServerSession().getServerPlatform() != null && getServerSession().getServerPlatform() instanceof WebSphere_7_Platform){
            warning("The test <testCreateEntityManagerFactory2> is not supported on WebSphere, because the ejb3.0 spec doesn't say that the PersistenceException must throw at this situation, just EclipseLink's implementation beyond the spec. So this test should not run on WebSphere 7.0.0.5");
            return;
        }
        EntityManagerFactory emf = null;
        PersistenceProvider provider = new PersistenceProvider();
        try{
            try {
                emf = provider.createEntityManagerFactory("default123", null);
            } catch (Exception e) {
                fail("Exception is not expected, but thrown:" + e);
            }
            assertNull(emf);
            try {
                emf = Persistence.createEntityManagerFactory("default123");
                fail("PersistenceException is expected");
            } catch (Exception e) {
                assertTrue("The exception should be a PersistenceException", e instanceof PersistenceException);
            }
        } finally{
            if (emf != null) {
                emf.close();
            }
        }
    }

    //Glassfish bug 702 - prevent primary key updates
    public void testPrimaryKeyUpdate() {
        EntityManager em = createEntityManager();
        beginTransaction(em);

        Employee emp = new Employee();
        emp.setFirstName("Groucho");
        emp.setLastName("Marx");
        em.persist(emp);

        Integer id = emp.getId();
        commitTransaction(em);

        beginTransaction(em);
        emp = em.merge(emp);
        emp.setId(id + 1);

        try {
            commitTransaction(em);
        } catch (Exception exception) {
            if (isTransactionActive(em)) {
                rollbackTransaction(em);
            }
            Throwable persistenceException = exception;
            // Remove an wrapping exceptions such as rollback, runtime, etc.
            while (persistenceException != null && !(persistenceException instanceof ValidationException)) {
                // In the server this is always a rollback exception, need to get nested exception.
                persistenceException = persistenceException.getCause();
            }
            if (persistenceException instanceof ValidationException) {
                ValidationException ve = (ValidationException) persistenceException;
                if (ve.getErrorCode() == ValidationException.PRIMARY_KEY_UPDATE_DISALLOWED) {
                    return;
                } else {
                    AssertionFailedError failure = new AssertionFailedError("Wrong error code for ValidationException: " + ve.getErrorCode());
                    failure.initCause(ve);
                    throw failure;
                }
            } else {
                AssertionFailedError failure = new AssertionFailedError("ValiationException expected, thrown: " + exception);
                failure.initCause(exception);
                throw failure;
            }
        } finally {
            closeEntityManager(em);
        }
        fail("No exception thrown when primary key update attempted.");
    }

    //Glassfish bug 702 - prevent primary key updates, same value is ok
    public void testPrimaryKeyUpdateSameValue() {
        EntityManager em = createEntityManager();
        beginTransaction(em);

        Employee emp = new Employee();
        emp.setFirstName("Harpo");
        emp.setLastName("Marx");
        em.persist(emp);

        Integer id = emp.getId();
        commitTransaction(em);

        beginTransaction(em);
        emp.setId(id);

        try {
            commitTransaction(em);
        } catch (Exception e) {
            if (isTransactionActive(em)){
                rollbackTransaction(em);
            }

            fail("Unexpected exception thrown: " + e.getClass());
        } finally {
            closeEntityManager(em);
        }
    }

    //Glassfish bug 702 - prevent primary key updates, overlapping PK/FK
    public void testPrimaryKeyUpdatePKFK() {
        EntityManager em = createEntityManager();
        beginTransaction(em);

        Employee emp = new Employee();
        emp.setFirstName("Groucho");
        emp.setLastName("Marx");
        em.persist(emp);

        Employee emp2 = new Employee();
        emp2.setFirstName("Harpo");
        emp2.setLastName("Marx");
        em.persist(emp2);

        PhoneNumber phone = new PhoneNumber("home", "415", "0007");
        emp.addPhoneNumber(phone);
        em.persist(phone);
        commitTransaction(em);

        beginTransaction(em);
        phone = em.merge(phone);
        emp2 = em.merge(emp2);
        phone.setOwner(emp2);

        try {
            commitTransaction(em);
        } catch (Exception exception) {
            if (isTransactionActive(em)) {
                rollbackTransaction(em);
            }
            Throwable persistenceException = exception;
            // Remove an wrapping exceptions such as rollback, runtime, etc.
            while (persistenceException != null && !(persistenceException instanceof ValidationException)) {
                // In the server this is always a rollback exception, need to get nested exception.
                persistenceException = persistenceException.getCause();
            }
            if (persistenceException instanceof ValidationException) {
                ValidationException ve = (ValidationException) persistenceException;
                if (ve.getErrorCode() == ValidationException.PRIMARY_KEY_UPDATE_DISALLOWED) {
                    return;
                } else {
                    AssertionFailedError failure = new AssertionFailedError("Wrong error code for ValidationException: " + ve.getErrorCode());
                    failure.initCause(ve);
                    throw failure;
                }
            } else {
                AssertionFailedError failure = new AssertionFailedError("ValiationException expected, thrown: " + exception);
                failure.initCause(exception);
                throw failure;
            }
        } finally {
            closeEntityManager(em);
        }
        fail("No exception thrown when primary key update attempted.");
    }
    // Test cascade merge on a detached entity
    public void testCascadeMergeDetached() {
        // setup
        Project p1 = new Project();
        p1.setName("Project1");
        Project p2 = new Project();
        p1.setName("Project2");
        Employee e1 = new Employee();
        e1.setFirstName("Employee1");
        Employee e2 = new Employee();
        e2.setFirstName("Employee2");

        EntityManager em = createEntityManager();
        beginTransaction(em);
        try {
            em.persist(p1);
            em.persist(p2);
            em.persist(e1);
            em.persist(e2);

            commitTransaction(em);
        } catch (RuntimeException re){
            if (isTransactionActive(em)){
                rollbackTransaction(em);
            }
            throw re;
        }
        closeEntityManager(em);
        // end of setup

        //p1,p2,e1,e2 are detached

        // associate relationships
        //p1 -> e1 (one-to-one)
        p1.setTeamLeader(e1);
        //e1 -> e2 (one-to-many)
        e1.addManagedEmployee(e2);
        //e2 -> p2 (many-to-many)
        e2.addProject(p2);
        p2.addTeamMember(e2);

        em = createEntityManager();
        beginTransaction(em);
        try {
            Project mp1 = em.merge(p1); // cascade merge
            assertTrue(em.contains(mp1));
            assertTrue("Managed instance and detached instance must not be same", mp1 != p1);

            Employee me1 = mp1.getTeamLeader();
            assertTrue("Cascade merge failed", em.contains(me1));
            assertTrue("Managed instance and detached instance must not be same", me1 != e1);

            Employee me2 = me1.getManagedEmployees().iterator().next();
            assertTrue("Cascade merge failed", em.contains(me2));
            assertTrue("Managed instance and detached instance must not be same", me2 != e2);

            Project mp2 = me2.getProjects().iterator().next();
            assertTrue("Cascade merge failed", em.contains(mp2));
            assertTrue("Managed instance and detached instance must not be same", mp2 != p2);

            commitTransaction(em);
        } catch (RuntimeException re){
            if (isTransactionActive(em)){
                rollbackTransaction(em);
            }
            throw re;
        }
        closeEntityManager(em);
    }

    // Test cascade merge on a managed entity
    // Test for GF#1139 - Cascade doesn't work when merging managed entity
    public void testCascadeMergeManaged() {
        // setup
        Project p1 = new Project();
        p1.setName("Project1");
        Project p2 = new Project();
        p1.setName("Project2");
        Employee e1 = new Employee();
        e1.setFirstName("Employee1");
        Employee e2 = new Employee();
        e2.setFirstName("Employee2");

        EntityManager em = createEntityManager();
        beginTransaction(em);
        try {
            em.persist(p1);
            em.persist(p2);
            em.persist(e1);
            em.persist(e2);

            commitTransaction(em);
        } catch (RuntimeException re){
            if (isTransactionActive(em)){
                rollbackTransaction(em);
            }
            throw re;
        }
        closeEntityManager(em);
        // end of setup

        //p1,p2,e1,e2 are detached
        em = createEntityManager();
        beginTransaction(em);
        try {
            Project mp1 = em.merge(p1);
            assertTrue(em.contains(mp1));
            assertTrue("Managed instance and detached instance must not be same", mp1 != p1);

            //p1 -> e1 (one-to-one)
            mp1.setTeamLeader(e1);
            mp1 = em.merge(mp1); // merge again - trigger cascade merge

            Employee me1 = mp1.getTeamLeader();
            assertTrue("Cascade merge failed", em.contains(me1));
            assertTrue("Managed instance and detached instance must not be same", me1 != e1);

            //e1 -> e2 (one-to-many)
            me1.addManagedEmployee(e2);
            me1 = em.merge(me1); // merge again - trigger cascade merge

            Employee me2 = me1.getManagedEmployees().iterator().next();
            assertTrue("Cascade merge failed", em.contains(me2));
            assertTrue("Managed instance and detached instance must not be same", me2 != e2);

            //e2 -> p2 (many-to-many)
            me2.addProject(p2);
            p2.addTeamMember(me2);
            me2 = em.merge(me2); // merge again - trigger cascade merge

            Project mp2 = me2.getProjects().iterator().next();
            assertTrue("Cascade merge failed", em.contains(mp2));
            assertTrue("Managed instance and detached instance must not be same", mp2 != p2);

            commitTransaction(em);
        } catch (RuntimeException re){
            if (isTransactionActive(em)){
                rollbackTransaction(em);
            }
            throw re;
        }
        closeEntityManager(em);
    }

    //Glassfish bug 1021 - allow cascading persist operation to non-entities
    public void testCascadePersistToNonEntitySubclass() {
        EntityManager em = createEntityManager();
        // added new setting for bug 237281
        InheritancePolicy ip = getServerSession().getDescriptor(Project.class).getInheritancePolicy();
        boolean describesNonPersistentSubclasses = ip.getDescribesNonPersistentSubclasses();
        ip.setDescribesNonPersistentSubclasses(true);

        beginTransaction(em);

        Employee emp = new Employee();
        emp.setFirstName("Albert");
        emp.setLastName("Einstein");

        SuperLargeProject s1 = new SuperLargeProject("Super 1");
        Collection projects = new ArrayList();
        projects.add(s1);
        emp.setProjects(projects);
        em.persist(emp);

        try {
            commitTransaction(em);
        } catch (Exception e) {
            if (isTransactionActive(em)){
                rollbackTransaction(em);
            }
            fail("Persist operation was not cascaded to related non-entity, thrown: " + e);
        } finally {
            ip.setDescribesNonPersistentSubclasses(describesNonPersistentSubclasses);
            closeEntityManager(em);
        }
    }

    /**
     * Bug 801
     * Test to ensure when property access is used and the underlying variable is changed the change
     * is correctly reflected in the database
     *
     * In this test we test making the change before the object is managed
     */
    public void testInitializeFieldForPropertyAccess(){
        Employee employee = new Employee();
        employee.setFirstName("Andy");
        employee.setLastName("Dufresne");
        Address address = new Address();
        address.setCity("Shawshank");
        employee.setAddressField(address);

        EntityManager em = createEntityManager();
        beginTransaction(em);
        em.persist(employee);
        try{
            commitTransaction(em);
        } catch (RuntimeException e){
            if (isTransactionActive(em)){
                rollbackTransaction(em);
            }
            throw e;
        }
        int id = employee.getId();

        clearCache();

        em = createEntityManager();
        beginTransaction(em);
        try {
            employee = em.find(Employee.class, id);
            address = employee.getAddress();

            assertTrue("The address was not persisted.", employee.getAddress() != null);
            assertTrue("The address was not correctly persisted.", employee.getAddress().getCity().equals("Shawshank"));
        } finally {
            employee.setAddress((Address)null);
            em.remove(address);
            em.remove(employee);
            commitTransaction(em);
        }
    }

    /**
     * Bug 801
     * Test to ensure when property access is used and the underlying variable is changed the change
     * is correctly reflected in the database
     *
     * In this test we test making the change after the object is managed
     */
    public void testSetFieldForPropertyAccess(){
        EntityManager em = createEntityManager();

        Employee employee = new Employee();
        employee.setFirstName("Andy");
        employee.setLastName("Dufresne");
        Address address = new Address();
        address.setCity("Shawshank");
        employee.setAddress(address);
        Employee manager = new Employee();
        manager.setFirstName("Bobby");
        manager.setLastName("Dufresne");
        employee.setManager(manager);

        beginTransaction(em);
        em.persist(employee);
        commitTransaction(em);
        int id = employee.getId();
        int addressId = address.getID();
        int managerId = manager.getId();

        beginTransaction(em);
        employee = em.find(Employee.class, id);
        employee.getAddress();

        address = new Address();
        address.setCity("Metropolis");
        employee.setAddress(address);
        manager = new Employee();
        manager.setFirstName("Metro");
        manager.setLastName("Dufresne");
        employee.setManagerField(manager);
        try {
            commitTransaction(em);
        } catch (RuntimeException e){
            if (isTransactionActive(em)){
                rollbackTransaction(em);
            }
            throw e;
        }

        clearCache();

        em = createEntityManager();
        beginTransaction(em);

        employee = em.find(Employee.class, id);
        address = employee.getAddress();
        manager = employee.getManager();

        assertTrue("The address was not persisted.", employee.getAddress() != null);
        assertTrue("The address was not correctly persisted.", employee.getAddress().getCity().equals("Metropolis"));

        assertTrue("The manager was not persisted.", employee.getManager() != null);
        assertTrue("The manager was not correctly persisted.", employee.getManager().getFirstName().equals("Metro"));

        Address initialAddress = em.find(Address.class, addressId);
        Employee initialManager = em.find(Employee.class, managerId);
        employee.setAddress((Address)null);
        employee.setManager(null);
        em.remove(address);
        em.remove(employee);
        em.remove(manager);
        em.remove(initialAddress);
        em.remove(initialManager);
        commitTransaction(em);
    }

    /**
     * Bug 801
     * Test to ensure when property access is used and the underlying variable is changed the change
     * is correctly reflected in the database
     *
     * In this test we test making the change after the object is refreshed
     */
    public void testSetFieldForPropertyAccessWithRefresh(){
        EntityManager em = createEntityManager();

        Employee employee = new Employee();
        employee.setFirstName("Andy");
        employee.setLastName("Dufresne");
        Address address = new Address();
        address.setCity("Shawshank");
        employee.setAddress(address);
        Employee manager = new Employee();
        manager.setFirstName("Bobby");
        manager.setLastName("Dufresne");
        employee.setManager(manager);

        beginTransaction(em);
        em.persist(employee);
        commitTransaction(em);
        int id = employee.getId();
        int addressId = address.getID();
        int managerId = manager.getId();

        beginTransaction(em);
        employee = em.getReference(Employee.class, employee.getId());
        em.refresh(employee);
        employee.getAddress();

        address = new Address();
        address.setCity("Metropolis");
        employee.setAddress(address);
        manager = new Employee();
        manager.setFirstName("Metro");
        manager.setLastName("Dufresne");
        employee.setManagerField(manager);
        try{
            commitTransaction(em);
        } catch (RuntimeException e){
            if (isTransactionActive(em)){
                rollbackTransaction(em);
            }
            throw e;
        }

        clearCache();

        em = createEntityManager();
        beginTransaction(em);

        employee = em.find(Employee.class, id);
        address = employee.getAddress();
        manager = employee.getManager();

        assertTrue("The address was not persisted.", employee.getAddress() != null);
        assertTrue("The address was not correctly persisted.", employee.getAddress().getCity().equals("Metropolis"));

        assertTrue("The manager was not persisted.", employee.getManager() != null);
        assertTrue("The manager was not correctly persisted.", employee.getManager().getFirstName().equals("Metro"));

        Address initialAddress = em.find(Address.class, addressId);
        Employee initialManager = em.find(Employee.class, managerId);
        employee.setAddress((Address)null);
        employee.setManager(null);
        em.remove(address);
        em.remove(employee);
        em.remove(manager);
        em.remove(initialAddress);
        em.remove(initialManager);
        commitTransaction(em);
    }

    /**
     * Bug 801
     * Test to ensure when property access is used and the underlying variable is changed the change
     * is correctly reflected in the database
     *
     * In this test we test making the change when an existing object is read into a new EM
     */
    public void testSetFieldForPropertyAccessWithNewEM(){
        EntityManager em = createEntityManager();

        Employee employee = new Employee();
        employee.setFirstName("Andy");
        employee.setLastName("Dufresne");
        Employee manager = new Employee();
        manager.setFirstName("Bobby");
        manager.setLastName("Dufresne");
        employee.setManager(manager);
        Address address = new Address();
        address.setCity("Shawshank");
        employee.setAddress(address);

        beginTransaction(em);
        em.persist(employee);
        commitTransaction(em);
        int id = employee.getId();
        int addressId = address.getID();
        int managerId = manager.getId();

        em = createEntityManager();

        beginTransaction(em);
        employee = em.find(Employee.class, id);
        employee.getAddress();
        employee.getManager();

        address = new Address();
        address.setCity("Metropolis");
        employee.setAddress(address);
        manager = new Employee();
        manager.setFirstName("Metro");
        manager.setLastName("Dufresne");
        employee.setManagerField(manager);
        try {
            commitTransaction(em);
        } catch (RuntimeException e){
            if (isTransactionActive(em)){
                rollbackTransaction(em);
            }
            throw e;
        }

        clearCache();

        em = createEntityManager();
        beginTransaction(em);
        employee = em.find(Employee.class, id);
        address = employee.getAddress();
        manager = employee.getManager();

        assertTrue("The address was not persisted.", employee.getAddress() != null);
        assertTrue("The address was not correctly persisted.", employee.getAddress().getCity().equals("Metropolis"));

        assertTrue("The manager was not persisted.", employee.getManager() != null);
        assertTrue("The manager was not correctly persisted.", employee.getManager().getFirstName().equals("Metro"));

        Address initialAddress = em.find(Address.class, addressId);
        Employee initialManager = em.find(Employee.class, managerId);

        employee.setAddress((Address)null);
        employee.setManager(null);
        em.remove(address);
        em.remove(employee);
        em.remove(manager);
        em.remove(initialAddress);
        em.remove(initialManager);
        commitTransaction(em);
    }

    //bug gf674 - EJBQL delete query with IS NULL in WHERE clause produces wrong sql
    public void testDeleteAllPhonesWithNullOwner() {
        EntityManager em = createEntityManager();
        beginTransaction(em);
        try {
            em.createQuery("DELETE FROM PhoneNumber ph WHERE ph.owner IS NULL").executeUpdate();
        } finally {
            if (isTransactionActive(em)){
                rollbackTransaction(em);
            }
            closeEntityManager(em);
        }
    }

     public void testDeleteAllProjectsWithNullTeamLeader() {
         if ((JUnitTestCase.getServerSession()).getPlatform().isSymfoware()) {
             getServerSession().logMessage("Test testDeleteAllProjectsWithNullTeamLeader skipped for this platform, "
                     + "Symfoware doesn't support UpdateAll/DeleteAll on multi-table objects (see rfe 298193).");
             return;
         }
         internalDeleteAllProjectsWithNullTeamLeader(Project.class);
     }
     public void testDeleteAllSmallProjectsWithNullTeamLeader() {
         internalDeleteAllProjectsWithNullTeamLeader(SmallProject.class);
     }
     public void testDeleteAllLargeProjectsWithNullTeamLeader() {
         if ((JUnitTestCase.getServerSession()).getPlatform().isSymfoware()) {
             getServerSession().logMessage("Test testDeleteAllLargeProjectsWithNullTeamLeader skipped for this platform, "
                     + "Symfoware doesn't support UpdateAll/DeleteAll on multi-table objects (see rfe 298193).");
             return;
         }
         internalDeleteAllProjectsWithNullTeamLeader(LargeProject.class);
     }

     public void testDeleteAllHugeProjectsWithNullTeamLeader() {
         if ((JUnitTestCase.getServerSession()).getPlatform().isSymfoware()) {
             getServerSession().logMessage("Test testDeleteAllLargeProjectsWithNullTeamLeader skipped for this platform, "
                     + "Symfoware doesn't support UpdateAll/DeleteAll on multi-table objects (see rfe 298193).");
             return;
         }
         internalDeleteAllProjectsWithNullTeamLeader(HugeProject.class);
     }

     public void testDeleteAllSpecialHugeProjectsWithNullTeamLeader() {
         if ((JUnitTestCase.getServerSession()).getPlatform().isSymfoware()) {
             getServerSession().logMessage("Test testDeleteAllSpecialHugeProjectsWithNullTeamLeader skipped for this platform, "
                     + "Symfoware doesn't support UpdateAll/DeleteAll on multi-table objects (see rfe 298193).");
             return;
         }
         internalDeleteAllProjectsWithNullTeamLeader(SpecialHugeProject.class);
     }

     protected void internalDeleteAllProjectsWithNullTeamLeader(Class cls) {
         String name = "testDeleteAllProjectsWithNull";
         Collection<Project> projectsToRemove = null;
         String className = cls.getSimpleName();

         // setup

         //create projects with a teamLeader to verify they don't get deleted as well
         Employee teamLead = new Employee();
         teamLead.setLastName(name);

         EntityManager em = this.createEntityManager();
         beginTransaction(em);
         try {
             // make sure there are no pre-existing Projects with this name
             em.createQuery("DELETE FROM Project p WHERE p.name = '"+name+"'").executeUpdate();
             em.flush();
             em.persist(teamLead);
             //this creates project types both with and without a teamLeader
             int projectTypes = createProjectsWithName(name, teamLead, em);
             em.flush();

             projectsToRemove = em.createQuery("SELECT p FROM "+className+" p WHERE p.name = '"+name+"' AND p.teamLeader IS NULL").getResultList();
             //expected number of projects left over where (teamLeader=null)
             int leftOverWOTL = projectTypes-projectsToRemove.size();

             em.clear();


             // test
             em.createQuery("DELETE FROM "+className+" p WHERE p.name = '"+name+"' AND p.teamLeader IS NULL").executeUpdate();

             // verify the correct projects with TeamLeaders=null were deleted
             List<Project> result = em.createQuery("SELECT OBJECT(p) FROM Project p WHERE p.name = '"+name+"'AND p.teamLeader IS NULL").getResultList();

             for (Project proj: result) {
                 if(cls.isInstance(proj)) {
                     fail("Target Class " + className +": object with null teamLeader of wrong type left: " + proj.getClass().getName());
                 }
             }
             assertEquals("Target Class " + className +
                     ": wrong number of projects left.  ", leftOverWOTL, result.size());

             //verify projects with teamLeaders weren't also deleted
             result = em.createQuery("SELECT OBJECT(p) FROM "+className+" p WHERE p.name = '"+name+"'").getResultList();
             if (result.isEmpty()) {
                 fail("Target Class " + className +": all objects were removed instead of just ones with null teamLeaders.");
             }
             boolean foundClasses  = true;
             if(result.size() != projectsToRemove.size()) {
                 fail("Target Class " + className +": objects left does not match expected result size: " + result.size());
             } else {
                 for (Project proj: result) {
                     if(cls.isInstance(proj) && proj.getTeamLeader()==null) {
                         fail("Target Class " + cls +": " + proj.getClass().getName()+" left with null TeamLeader");
                     }
                 }
             }

         } finally {
             closeEntityManagerAndTransaction(em);
         }
     }

    // gf1408: DeleteAll and UpdateAll queries broken on some db platforms;
    // gf1451: Complex updates to null using temporary storage do not work on Derby;
    // gf1860: TopLink provides too few values.
    // The tests forces the use of temporary storage to test null assignment to an integer field
    // on all platforms.
    public void testUpdateUsingTempStorage() {
        internalUpdateUsingTempStorage(false);
    }
    public void testUpdateUsingTempStorageWithParameter() {
        internalUpdateUsingTempStorage(true);
    }
    protected void internalUpdateUsingTempStorage(boolean useParameter) {
        if ((JUnitTestCase.getServerSession()).getPlatform().isSymfoware()) {
            getServerSession().logMessage("Test testUpdateUsingTempStorage* skipped for this platform, "
                    + "Symfoware doesn't support UpdateAll/DeleteAll on multi-table objects (see rfe 298193).");
            return;
        } else if ((JUnitTestCase.getServerSession()).getPlatform().isPervasive()) {
            getServerSession().logMessage("Test testUpdateUsingTempStorage* skipped for this platform. "
                                          + "Pervasive does not support dynamic parameters in the Select list.");
            return;
        }

        String firstName = "testUpdateUsingTempStorage";
        int n = 3;

        // setup
        EntityManager em = createEntityManager();
        try {
            beginTransaction(em);
            // make sure there are no pre-existing objects with this name
            em.createQuery("DELETE FROM Employee e WHERE e.firstName = '"+firstName+"'").executeUpdate();
            em.createQuery("DELETE FROM Address a WHERE a.country = '"+firstName+"'").executeUpdate();
            // populate Employees
            for(int i=1; i<=n; i++) {
                Employee emp = new Employee();
                emp.setFirstName(firstName);
                emp.setLastName(Integer.toString(i));
                emp.setSalary(i*100);
                emp.setRoomNumber(i);

                Address address = new Address();
                address.setCountry(firstName);
                address.setCity(Integer.toString(i));

                emp.setAddress(address);

                em.persist(emp);
            }
            commitTransaction(em);
        } catch (RuntimeException ex){
            if (isTransactionActive(em)){
                 rollbackTransaction(em);
            }
            throw ex;
        } finally {
            closeEntityManager(em);
        }

        // test
        em = createEntityManager();
        beginTransaction(em);
        int nUpdated = 0;
        try {
            if(useParameter) {
                nUpdated = em.createQuery("UPDATE Employee e set e.salary = e.roomNumber, e.roomNumber = e.salary, e.address = :address where e.firstName = '" + firstName + "'").setParameter("address", null).executeUpdate();
            } else {
                nUpdated = em.createQuery("UPDATE Employee e set e.salary = e.roomNumber, e.roomNumber = e.salary, e.address = null where e.firstName = '" + firstName + "'").executeUpdate();
            }
            commitTransaction(em);
        } finally {
            if (isTransactionActive(em)){
                rollbackTransaction(em);
            }
            closeEntityManager(em);
        }

        // verify
        String error = null;
        em = createEntityManager();
        try {
            List result = em.createQuery("SELECT OBJECT(e) FROM Employee e WHERE e.firstName = '"+firstName+"'").getResultList();
            int nReadBack = result.size();
            if(n != nUpdated) {
                error = "n = "+n+", but nUpdated ="+nUpdated+";";
            }
            if(n != nReadBack) {
                error = " n = "+n+", but nReadBack ="+nReadBack+";";
            }
            for(int i=0; i<nReadBack; i++) {
                Employee emp = (Employee)result.get(i);
                if(emp.getAddress() != null) {
                    error = " Employee "+emp.getLastName()+" still has address;";
                }
                int ind = Integer.parseInt(emp.getLastName());
                if(emp.getSalary() != ind) {
                    error = " Employee "+emp.getLastName()+" has wrong salary "+emp.getSalary()+";";
                }
                if(emp.getRoomNumber() != ind*100) {
                    error = " Employee "+emp.getLastName()+" has wrong roomNumber "+emp.getRoomNumber()+";";
                }
            }
        } catch (RuntimeException ex) {
            if (usesSOP() && !isSOPRecoverable()) {
                if (ex instanceof PersistenceException) {
                    if (ex.getCause() instanceof QueryException && ((QueryException)ex.getCause()).getErrorCode() == QueryException.SOP_OBJECT_IS_NOT_FOUND) {
                        // getResultList is expected to fail because SOP field is set to null after bulk update
                    } else {
                        fail("Wrong cause of PersistenceException: " + ex.getCause());
                    }
                } else {
                    fail("PersistenceException was expected");
                }
            } else {
                throw ex;
            }
        } finally {
            closeEntityManager(em);
        }

        // clean up
        em = createEntityManager();
        try {
            beginTransaction(em);
            // make sure there are no objects left with this name
            em.createQuery("DELETE FROM Employee e WHERE e.firstName = '"+firstName+"'").executeUpdate();
            em.createQuery("DELETE FROM Address a WHERE a.country = '"+firstName+"'").executeUpdate();
            commitTransaction(em);
        } catch (RuntimeException ex){
            if (isTransactionActive(em)){
                 rollbackTransaction(em);
            }
            throw ex;
        } finally {
            closeEntityManager(em);
        }

        if(error != null) {
            fail(error);
        }
    }

  /*this creates project types both with and without a teamLeader if one is passed in, and
   * returns the number of project types created (2x the number of project instances will have been created if a team lead is specified)
   */
    protected int createProjectsWithName(String name, Employee teamLeader, EntityManager em) {

        Project p = new Project();
        p.setName(name);
        em.persist(p);
        SmallProject sp = new SmallProject();
        sp.setName(name);
        em.persist(sp);
        LargeProject lp = new LargeProject();
        lp.setName(name);
        em.persist(lp);
        HugeProject hp = new HugeProject();
        hp.setName(name);
        em.persist(hp);
        SpecialHugeProject shp = new SpecialHugeProject();
        shp.setName(name);
        em.persist(shp);

        if(teamLeader != null) {
            Project pWTL = new Project();
            pWTL.setName(name);
            pWTL.setTeamLeader(teamLeader);
            em.persist(pWTL);
            SmallProject spWTL = new SmallProject();
            spWTL.setName(name);
            spWTL.setTeamLeader(teamLeader);
            em.persist(spWTL);
            LargeProject lpWTL = new LargeProject();
            lpWTL.setName(name);
            lpWTL.setTeamLeader(teamLeader);
            em.persist(lpWTL);
            HugeProject hpWTL = new HugeProject();
            hpWTL.setName(name);
            hpWTL.setTeamLeader(teamLeader);
            em.persist(hpWTL);
            SpecialHugeProject shpWTL = new SpecialHugeProject();
            shpWTL.setName(name);
            shpWTL.setTeamLeader(teamLeader);
            em.persist(shpWTL);
        }
        //change this if this method creates a new project subclass type.
        return 5;
    }

    protected void deleteProjectsWithName(String name) {
        EntityManager em = createEntityManager();
        try {
            beginTransaction(em);

            em.createQuery("DELETE FROM Project p WHERE p.name = '"+name+"'").executeUpdate();

            commitTransaction(em);
        } finally {
            closeEntityManagerAndTransaction(em);
        }
    }

    public void testUpdateAllSmallProjects() {
        internalTestUpdateAllProjects(SmallProject.class);
    }
    public void testUpdateAllLargeProjects() {
        internalTestUpdateAllProjects(LargeProject.class);
    }
    public void testUpdateAllHugeProjects() {
        internalTestUpdateAllProjects(HugeProject.class);
    }
    public void testUpdateAllSpecialHugeProjects() {
        internalTestUpdateAllProjects(SpecialHugeProject.class);
    }
    public void testUpdateAllProjects() {
        internalTestUpdateAllProjects(Project.class);
    }
    protected void internalTestUpdateAllProjects(Class cls) {
        if ((JUnitTestCase.getServerSession()).getPlatform().isSymfoware()) {
            getServerSession().logMessage("Test testUpdateAll*Projects skipped for this platform, "
                    + "Symfoware doesn't support UpdateAll/DeleteAll on multi-table objects (see rfe 298193).");
            return;
        }

        String className = Helper.getShortClassName(cls);
        String name = "testUpdateAllProjects";
        String newName = "testUpdateAllProjectsNEW";
        HashMap map = null;
        boolean ok = false;

        try {
            // setup

            // save the original names of projects: will set them back in cleanup
            // to restore the original state.
            EntityManager em = createEntityManager();
            List projects = em.createQuery("SELECT OBJECT(p) FROM Project p").getResultList();
            map = new HashMap(projects.size());
            for(int i=0; i<projects.size(); i++) {
                Project p = (Project)projects.get(i);
                map.put(p.getId(), p.getName());
            }

            // populate Projects - necessary only if no SmallProject and/or LargeProject objects already exist.
            beginTransaction(em);
            try{
                createProjectsWithName(name, null, em);
                commitTransaction(em);
            } finally {
                closeEntityManagerAndTransaction(em);
            }

            // test
            em = createEntityManager();
            beginTransaction(em);
            try {
                em.createQuery("UPDATE "+className+" p set p.name = '"+newName+"'").executeUpdate();
                commitTransaction(em);
            } finally {
                closeEntityManagerAndTransaction(em);
            }

            // verify
            em = createEntityManager();
            String errorMsg = "";
            try {
                projects = em.createQuery("SELECT OBJECT(p) FROM Project p").getResultList();
                for(int i=0; i<projects.size(); i++) {
                    Project p = (Project)projects.get(i);
                    String readName = p.getName();
                    if(cls.isInstance(p)) {
                        if(!newName.equals(readName)) {
                            errorMsg = errorMsg + "haven't updated name: " + p + "; ";
                        }
                    } else {
                        if(newName.equals(readName)) {
                            errorMsg = errorMsg + "have updated name: " + p + "; ";
                        }
                    }
                }
            } catch (RuntimeException ex) {
                if (usesSOP() && !isSOPRecoverable()) {
                    if (ex instanceof PersistenceException) {
                        if (ex.getCause() instanceof QueryException && ((QueryException)ex.getCause()).getErrorCode() == QueryException.SOP_OBJECT_IS_NOT_FOUND) {
                            // getResultList is expected to fail because SOP field is set to null after bulk update
                        } else {
                            fail("Wrong cause of PersistenceException: " + ex.getCause());
                        }
                    } else {
                        fail("PersistenceException was expected");
                    }
                } else {
                    throw ex;
                }
            } finally {
                closeEntityManager(em);
            }

            if(errorMsg.length() > 0) {
                fail(errorMsg);
            } else {
                ok = true;
            }
        } finally {
            // clean-up
            try {
                if(map != null) {
                    EntityManager em = createEntityManager();
                    beginTransaction(em);
                    Query query = em.createQuery("SELECT OBJECT(p) FROM Project p");
                    if (usesSOP() && !isSOPRecoverable()) {
                        // otherwise will fail because SOP field is set to null after bulk update
                        query.setHint(QueryHints.SERIALIZED_OBJECT, "false");
                    }
                    List projects = query.getResultList();
                    try {
                        for(int i=0; i<projects.size(); i++) {
                            Project p = (Project)projects.get(i);
                            String oldName = (String)map.get(((Project)projects.get(i)).getId());
                            p.setName(oldName);
                        }
                        commitTransaction(em);
                    } finally {
                        closeEntityManagerAndTransaction(em);
                    }
                }
                // delete projects that createProjectsWithName has created in setup.
                //these will be left over under the newName
                deleteProjectsWithName(newName);
            } catch (RuntimeException ex) {
                // eat clean-up exception in case the test failed
                if(ok) {
                    throw ex;
                }
            }
        }
    }

    public void testUpdateAllSmallProjectsWithName() {
        internalTestUpdateAllProjectsWithName(SmallProject.class);
    }
    public void testUpdateAllLargeProjectsWithName() {
        internalTestUpdateAllProjectsWithName(LargeProject.class);
    }
    public void testUpdateAllHugeProjectsWithName() {
        internalTestUpdateAllProjectsWithName(HugeProject.class);
    }
    public void testUpdateAllSpecialHugeProjectsWithName() {
        internalTestUpdateAllProjectsWithName(SpecialHugeProject.class);
    }
    public void testUpdateAllProjectsWithName() {
        internalTestUpdateAllProjectsWithName(Project.class);
    }
    protected void internalTestUpdateAllProjectsWithName(Class cls) {
        if ((JUnitTestCase.getServerSession()).getPlatform().isSymfoware()) {
            getServerSession().logMessage("Test testUpdateAll*ProjectsWithName skipped for this platform, "
                    + "Symfoware doesn't support UpdateAll/DeleteAll on multi-table objects (see rfe 298193).");
            return;
        }
        String className = Helper.getShortClassName(cls);
        String name = "testUpdateAllProjects";
        String newName = "testUpdateAllProjectsNEW";
        boolean ok = false;

        try {
            // setup
            // make sure no projects with the specified names exist
            deleteProjectsWithName(name);
            deleteProjectsWithName(newName);
            // populate Projects
            EntityManager em = createEntityManager();
            beginTransaction(em);
            try {
                createProjectsWithName(name, null, em);
                commitTransaction(em);
            } finally {
                closeEntityManagerAndTransaction(em);
            }

            // test
            em = createEntityManager();
            beginTransaction(em);
            try {
                em.createQuery("UPDATE "+className+" p set p.name = '"+newName+"' WHERE p.name = '"+name+"'").executeUpdate();
                commitTransaction(em);
            } finally {
                closeEntityManagerAndTransaction(em);
            }

            // verify
            em = createEntityManager();
            String errorMsg = "";
            try {
                List projects = em.createQuery("SELECT OBJECT(p) FROM Project p WHERE p.name = '"+newName+"' OR p.name = '"+name+"'").getResultList();
                for(int i=0; i<projects.size(); i++) {
                    Project p = (Project)projects.get(i);
                    String readName = p.getName();
                    if(cls.isInstance(p)) {
                        if(!readName.equals(newName)) {
                            errorMsg = errorMsg + "haven't updated name: " + p + "; ";
                        }
                    } else {
                        if(readName.equals(newName)) {
                            errorMsg = errorMsg + "have updated name: " + p + "; ";
                        }
                    }
                }
            } catch (RuntimeException ex) {
                if (usesSOP() && !isSOPRecoverable()) {
                    if (ex instanceof PersistenceException) {
                        if (ex.getCause() instanceof QueryException && ((QueryException)ex.getCause()).getErrorCode() == QueryException.SOP_OBJECT_IS_NOT_FOUND) {
                            // getResultList is expected to fail because SOP field is set to null after bulk update
                        } else {
                            fail("Wrong cause of PersistenceException: " + ex.getCause());
                        }
                    } else {
                        fail("PersistenceException was expected");
                    }
                } else {
                    throw ex;
                }
            } finally {
                closeEntityManager(em);
            }

            if(errorMsg.length() > 0) {
                fail(errorMsg);
            } else {
                ok = true;
            }
        } finally {
            // clean-up
            // make sure no projects with the specified names left
            try {
                deleteProjectsWithName(name);
                deleteProjectsWithName(newName);
            } catch (RuntimeException ex) {
                // eat clean-up exception in case the test failed
                if(ok) {
                    throw ex;
                }
            }
        }
    }

    public void testUpdateAllSmallProjectsWithNullTeamLeader() {
        internalTestUpdateAllProjectsWithNullTeamLeader(SmallProject.class);
    }
    public void testUpdateAllLargeProjectsWithNullTeamLeader() {
        internalTestUpdateAllProjectsWithNullTeamLeader(LargeProject.class);
    }
    public void testUpdateAllProjectsWithNullTeamLeader() {
        internalTestUpdateAllProjectsWithNullTeamLeader(Project.class);
    }
    public void testUpdateAllSpecialHugeProjectsWithNullTeamLeader() {
        internalTestUpdateAllProjectsWithNullTeamLeader(SpecialHugeProject.class);
    }
    protected void internalTestUpdateAllProjectsWithNullTeamLeader(Class cls) {
        if ((JUnitTestCase.getServerSession()).getPlatform().isSymfoware()) {
            getServerSession().logMessage("Test testUpdateAll*ProjectsWithNullTeamLeader skipped for this platform, "
                    + "Symfoware doesn't support UpdateAll/DeleteAll on multi-table objects (see rfe 298193).");
            return;
        } else if ((JUnitTestCase.getServerSession()).getPlatform().isPervasive()) {
            getServerSession().logMessage("Test testUpdateAll*ProjectsWithNullTeamLeader skipped for this platform." );
            return;
        }
        String className = Helper.getShortClassName(cls);
        String name = "testUpdateAllProjects";
        String newName = "testUpdateAllProjectsNEW";
        Employee empTemp = null;
        boolean ok = false;

        try {
            // setup
            // make sure no projects with the specified names exist
            deleteProjectsWithName(name);
            deleteProjectsWithName(newName);
            EntityManager em = createEntityManager();
            Employee emp = null;
            List employees = em.createQuery("SELECT OBJECT(e) FROM Employee e").getResultList();
            if(employees.size() > 0) {
                emp = (Employee)employees.get(0);
            } else {
                beginTransaction(em);
                try {
                    emp = new Employee();
                    emp.setFirstName(name);
                    emp.setLastName("TeamLeader");
                    em.persist(emp);
                    commitTransaction(em);
                    empTemp = emp;
                } finally {
                    closeEntityManagerAndTransaction(em);
                }
            }
            em = createEntityManager();
            beginTransaction(em);
            // populate Projects
            try {
                createProjectsWithName(name, emp, em);
                commitTransaction(em);
            } finally {
                closeEntityManagerAndTransaction(em);
            }

            // test
            em = createEntityManager();
            beginTransaction(em);
            try {
                em.createQuery("UPDATE "+className+" p set p.name = '"+newName+"' WHERE p.name = '"+name+"' AND p.teamLeader IS NULL").executeUpdate();
                commitTransaction(em);
            } finally {
                closeEntityManagerAndTransaction(em);
            }

            // verify
            em = createEntityManager();
            String errorMsg = "";
            try {
                List projects = em.createQuery("SELECT OBJECT(p) FROM Project p WHERE p.name = '"+newName+"' OR p.name = '"+name+"'").getResultList();
                for(int i=0; i<projects.size(); i++) {
                    Project p = (Project)projects.get(i);
                    String readName = p.getName();
                    if(cls.isInstance(p) && p.getTeamLeader()==null) {
                        if(!readName.equals(newName)) {
                            errorMsg = errorMsg + "haven't updated name: " + p + "; ";
                        }
                    } else {
                        if(readName.equals(newName)) {
                            errorMsg = errorMsg + "have updated name: " + p + "; ";
                        }
                    }
                }
            } catch (RuntimeException ex) {
                if (usesSOP() && !isSOPRecoverable()) {
                    if (ex instanceof PersistenceException) {
                        if (ex.getCause() instanceof QueryException && ((QueryException)ex.getCause()).getErrorCode() == QueryException.SOP_OBJECT_IS_NOT_FOUND) {
                            // getResultList is expected to fail because SOP field is set to null after bulk update
                        } else {
                            fail("Wrong cause of PersistenceException: " + ex.getCause());
                        }
                    } else {
                        fail("PersistenceException was expected");
                    }
                } else {
                    throw ex;
                }
            } finally {
                closeEntityManager(em);
            }

            if(errorMsg.length() > 0) {
                fail(errorMsg);
            } else {
                ok = true;
            }
        } finally {
            // clean-up
            // make sure no projects with the specified names exist
            try {
                deleteProjectsWithName(name);
                deleteProjectsWithName(newName);
                if(empTemp != null) {
                    EntityManager em = createEntityManager();
                    beginTransaction(em);
                    try {
                        em.createQuery("DELETE FROM Employee e WHERE e.id = '"+empTemp.getId()+"'").executeUpdate();
                        commitTransaction(em);
                    }  finally {
                        closeEntityManagerAndTransaction(em);
                    }
                }
            } catch (RuntimeException ex) {
                // eat clean-up exception in case the test failed
                if(ok) {
                    throw ex;
                }
            }
        }
    }

    public void testRollbackOnlyOnException() {
        EntityManager em = createEntityManager();
        beginTransaction(em);
        try {
            Employee emp = em.find(Employee.class, "");
            emp.toString();
            fail("IllegalArgumentException has not been thrown");
        } catch(IllegalArgumentException ex) {
            if (isOnServer()) {
                assertTrue("Transaction is not roll back only", getRollbackOnly(em));
            } else {
                assertTrue("Transaction is not roll back only", em.getTransaction().getRollbackOnly());
            }
        } finally {
            rollbackTransaction(em);
            closeEntityManager(em);
        }
    }

    public void testClosedEmShouldThrowException() {
        // Close is not used on server.
        if (isOnServer()) {
            return;
        }
        EntityManager em = createEntityManager();
        closeEntityManager(em);
        String errorMsg = "";

        try {
            em.clear();
            errorMsg = errorMsg + "; em.clear() didn't throw exception";
        } catch(IllegalStateException ise) {
            // expected
        } catch(RuntimeException ex) {
            errorMsg = errorMsg + "; em.clear() threw wrong exception: " + ex.getMessage();
        }
        try {
            closeEntityManager(em);
            errorMsg = errorMsg + "; closeEntityManager(em) didn't throw exception";
        } catch(IllegalStateException ise) {
            // expected
        } catch(RuntimeException ex) {
            errorMsg = errorMsg + "; closeEntityManager(em) threw wrong exception: " + ex.getMessage();
        }
        try {
            em.contains(null);
            errorMsg = errorMsg + "; em.contains() didn't throw exception";
        } catch(IllegalStateException ise) {
            // expected
        } catch(RuntimeException ex) {
            errorMsg = errorMsg + "; em.contains threw() wrong exception: " + ex.getMessage();
        }
        try {
            em.getDelegate();
            errorMsg = errorMsg + "; em.getDelegate() didn't throw exception";
        } catch(IllegalStateException ise) {
            // expected
        } catch(RuntimeException ex) {
            errorMsg = errorMsg + "; em.getDelegate() threw wrong exception: " + ex.getMessage();
        }
        try {
            em.getReference(Employee.class, 1);
            errorMsg = errorMsg + "; em.getReference() didn't throw exception";
        } catch(IllegalStateException ise) {
            // expected
        } catch(RuntimeException ex) {
            errorMsg = errorMsg + "; em.getReference() threw wrong exception: " + ex.getMessage();
        }
        try {
            em.joinTransaction();
            errorMsg = errorMsg + "; em.joinTransaction() didn't throw exception";
        } catch(IllegalStateException ise) {
            // expected
        } catch(RuntimeException ex) {
            errorMsg = errorMsg + "; em.joinTransaction() threw wrong exception: " + ex.getMessage();
        }
        try {
            em.lock(null, null);
            errorMsg = errorMsg + "; em.lock() didn't throw exception";
        } catch(IllegalStateException ise) {
            // expected
        } catch(RuntimeException ex) {
            errorMsg = errorMsg + "; em.lock() threw wrong exception: " + ex.getMessage();
        }

        if(errorMsg.length() > 0) {
            fail(errorMsg);
        }
    }

    //gf 1217 - Ensure join table defaults correctly when 'mappedby' not specified
    public void testOneToManyDefaultJoinTableName() {
        Department dept  = new Department();
        Employee manager = new Employee();
        dept.addManager(manager);

        EntityManager em = createEntityManager();
        try {
            beginTransaction(em);
            em.persist(dept);
            commitTransaction(em);
        }catch (RuntimeException e) {
            throw e;
        }finally {
            if (isTransactionActive(em)){
                rollbackTransaction(em);
            }
            closeEntityManager(em);
        }
    }

    // gf1732
    public void testMultipleEntityManagerFactories() {
        // TODO: This does not work on the server but should.
        if (isOnServer()) {
            return;
        }

        // close the original factory
        closeEntityManagerFactory();
        // create the new one - not yet deployed
        EntityManagerFactory factory1 =  getEntityManagerFactory();
        // create the second one
        EntityManagerFactory factory2 =  Persistence.createEntityManagerFactory("default", JUnitTestCaseHelper.getDatabaseProperties());
        // deploy
        factory2.createEntityManager();
        // close
        factory2.close();

        try {
            // now try to getEM from the first one - this used to throw exception
            factory1.createEntityManager();
            // don't close factory1 if all is well
        } catch (PersistenceException ex) {
            fail("factory1.createEM threw exception: " + ex.getMessage());
            factory1.close();
        }
    }

    // gf2074: EM.clear throws NPE
    public void testClearEntityManagerWithoutPersistenceContext() {
        EntityManager em = createEntityManager();
        try {
            em.clear();
        }finally {
            closeEntityManager(em);
        }
    }

    // Used by testClearEntityManagerWithoutPersistenceContextSimulateJTA().
    // At first tried to use JTATransactionController class, but that introduced dependencies
    // on jakarta.transaction package (and therefore failed in gf entity persistence tests).
    static class DummyExternalTransactionController extends org.eclipse.persistence.transaction.AbstractTransactionController {
        @Override
        public boolean isRolledBack_impl(Object status){return false;}
        @Override
        protected void registerSynchronization_impl(org.eclipse.persistence.transaction.AbstractSynchronizationListener listener, Object txn) throws Exception{}
        @Override
        protected Object getTransaction_impl() throws Exception {return null;}
        @Override
        protected Object getTransactionKey_impl(Object transaction) throws Exception {return null;}
        @Override
        protected Object getTransactionStatus_impl() throws Exception {return null;}
        @Override
        protected void beginTransaction_impl() throws Exception{}
        @Override
        protected void commitTransaction_impl() throws Exception{}
        @Override
        protected void rollbackTransaction_impl() throws Exception{}
        @Override
        protected void markTransactionForRollback_impl() throws Exception{}
        @Override
        protected boolean canBeginTransaction_impl(Object status){return false;}
        @Override
        protected boolean canCommitTransaction_impl(Object status){return false;}
        @Override
        protected boolean canRollbackTransaction_impl(Object status){return false;}
        @Override
        protected boolean canIssueSQLToDatabase_impl(Object status){return false;}
        @Override
        protected boolean canMergeUnitOfWork_impl(Object status){return false;}
        @Override
        protected String statusToString_impl(Object status){return "";}
    }
    // gf2074: EM.clear throws NPE (JTA case)
    public void testClearEntityManagerWithoutPersistenceContextSimulateJTA() {
        EntityManager em = createEntityManager();
        ServerSession ss = getServerSession();
        closeEntityManager(em);
        // in non-JTA case session doesn't have external transaction controller
        boolean hasExternalTransactionController = ss.hasExternalTransactionController();
        if(!hasExternalTransactionController) {
            // simulate JTA case
            ss.setExternalTransactionController(new DummyExternalTransactionController());
        }
        try {
            testClearEntityManagerWithoutPersistenceContext();
        }finally {
            if(!hasExternalTransactionController) {
                // remove the temporary set TransactionController
                ss.setExternalTransactionController(null);
            }
        }
    }

    public void testDescriptorNamedQuery(){
        ReadAllQuery query = new ReadAllQuery(Employee.class);
        ExpressionBuilder builder = new ExpressionBuilder();
        Expression exp = builder.get("firstName").equal(builder.getParameter("fName"));
        exp = exp.and(builder.get("lastName").equal(builder.getParameter("lName")));
        query.setSelectionCriteria(exp);
        query.addArgument("fName", String.class);
        query.addArgument("lName", String.class);

        EntityManager em = createEntityManager();
        Session session = getServerSession();
        ClassDescriptor descriptor = session.getDescriptor(Employee.class);
        descriptor.getQueryManager().addQuery("findByFNameLName", query);

        beginTransaction(em);
        try {
            Employee emp = new Employee();
            emp.setFirstName("Melvin");
            emp.setLastName("Malone");
            em.persist(emp);
            em.flush();

            Query ejbQuery = ((org.eclipse.persistence.jpa.JpaEntityManager)em.getDelegate()).createDescriptorNamedQuery("findByFNameLName", Employee.class);
            List results = ejbQuery.setParameter("fName", "Melvin").setParameter("lName", "Malone").getResultList();

            assertTrue("returned collection size was "+results.size(), results.size() == 1);
            emp = (Employee)results.get(0);
            assertTrue(emp.getFirstName().equals("Melvin"));
            assertTrue(emp.getLastName().equals("Malone"));
        } finally {
            rollbackTransaction(em);
            closeEntityManager(em);
        }

        descriptor.getQueryManager().removeQuery("findByFNameLName");
    }

    public void testDescriptorNamedQueryForMultipleQueries(){
        ReadAllQuery query = new ReadAllQuery(Employee.class);
        ExpressionBuilder builder = new ExpressionBuilder();
        Expression exp = builder.get("firstName").equal(builder.getParameter("fName"));
        exp = exp.and(builder.get("lastName").equal(builder.getParameter("lName")));
        query.setSelectionCriteria(exp);
        query.addArgument("fName", String.class);
        query.addArgument("lName", String.class);

        ReadAllQuery query2 = new ReadAllQuery(Employee.class);


        EntityManager em = createEntityManager();
        Session session = getServerSession();
        ClassDescriptor descriptor = session.getDescriptor(Employee.class);
        descriptor.getQueryManager().addQuery("findEmployees", query);
        descriptor.getQueryManager().addQuery("findEmployees", query2);

        beginTransaction(em);
        try {
            Employee emp = new Employee();
            emp.setFirstName("Melvin");
            emp.setLastName("Malone");
            em.persist(emp);
            em.flush();

            Vector args = new Vector(2);
            args.addElement(String.class);
            args.addElement(String.class);
            Query ejbQuery = ((org.eclipse.persistence.jpa.JpaEntityManager)em.getDelegate()).createDescriptorNamedQuery("findEmployees", Employee.class, args);
            List results = ejbQuery.setParameter("fName", "Melvin").setParameter("lName", "Malone").getResultList();

            assertTrue(results.size() == 1);
            emp = (Employee)results.get(0);
            assertTrue(emp.getFirstName().equals("Melvin"));
            assertTrue(emp.getLastName().equals("Malone"));
        } finally {
            rollbackTransaction(em);
            closeEntityManager(em);
        }

        descriptor.getQueryManager().removeQuery("findEmployees");
    }

    // GF 2621
    public void testDoubleMerge(){
        EntityManager em = createEntityManager();

        Employee employee = new Employee();
        employee.setId(44);
        employee.setVersion(0);
        employee.setFirstName("Alfie");

        Employee employee2 = new Employee();
        employee2.setId(44);
        employee2.setVersion(0);
        employee2.setFirstName("Phillip");
        Employee result = null;
        try {
            beginTransaction(em);
            result = em.merge(employee);
            result = em.merge(employee2);
            assertTrue("The firstName was not merged properly", result.getFirstName().equals(employee2.getFirstName()));
            em.flush();
        } catch (PersistenceException e){
            fail("A double merge of an object with the same key, caused two inserts instead of one.");
        } finally {
            rollbackTransaction(em);
        }
    }

    // gf 3032
    public void testPessimisticLockHintStartsTransaction(){
        if (isOnServer()) {
            // Extended persistence context are not supported in the server.
            return;
        }
        if (!isSelectForUpateSupported()) {
            return;
        }
        if ((JUnitTestCase.getServerSession()).getPlatform().isHANA()) {
            // HANA currently doesn't support pessimistic locking with queries on multiple tables
            // feature is under development (see bug 384129), but test should be skipped for the time being
            return;
        }
        EntityManagerImpl em = (EntityManagerImpl)createEntityManager();
        beginTransaction(em);
        Query query = em.createNamedQuery("findAllEmployeesByFirstName");
        query.setHint("eclipselink.pessimistic-lock", PessimisticLock.Lock);
        query.setParameter("firstname", "Sarah");
        List results = query.getResultList();
        results.toString();
        assertTrue("The extended persistence context is not in a transaction after a pessmimistic lock query", em.getActivePersistenceContext(em.getTransaction()).getParent().isInTransaction());
        rollbackTransaction(em);
    }

    /**
     * Test that all of the classes in the advanced model were weaved as expected.
     */
    public void testWeaving() {
        // Only test if weaving was on, test runs without weaving must set this system property.
        if (isWeavingEnabled()) {
            internalTestWeaving(new Employee(), isWeavingForChangeTrackingEnabled(), isWeavingForFetchGroupsEnabled(), true);
            internalTestWeaving(new FormerEmployment(), isWeavingForChangeTrackingEnabled(), isWeavingForFetchGroupsEnabled(), false);
            internalTestWeaving(new Address(), isWeavingForChangeTrackingEnabled(), isWeavingForFetchGroupsEnabled(), false);
            internalTestWeaving(new PhoneNumber(), isWeavingForChangeTrackingEnabled(), isWeavingForFetchGroupsEnabled(), false);
            internalTestWeaving(new EmploymentPeriod(), isWeavingForChangeTrackingEnabled(), isWeavingForFetchGroupsEnabled(), false);
            internalTestWeaving(new Buyer(), false, isWeavingForFetchGroupsEnabled(), false);  // field-locking
            internalTestWeaving(new GoldBuyer(), false, isWeavingForFetchGroupsEnabled(), false);  // field-locking
            internalTestWeaving(new PlatinumBuyer(), false, isWeavingForFetchGroupsEnabled(), false);  // field-locking
            internalTestWeaving(new Department(), isWeavingForChangeTrackingEnabled(), isWeavingForFetchGroupsEnabled(), false);  // eager 1-m
            internalTestWeaving(new Golfer(), isWeavingForChangeTrackingEnabled(), isWeavingForFetchGroupsEnabled(), false);
            internalTestWeaving(new GolferPK(), isWeavingForChangeTrackingEnabled(), isWeavingForFetchGroupsEnabled(), false);
            internalTestWeaving(new SmallProject(), isWeavingForChangeTrackingEnabled(), isWeavingForFetchGroupsEnabled(), false);
            internalTestWeaving(new LargeProject(), isWeavingForChangeTrackingEnabled(), isWeavingForFetchGroupsEnabled(), false);
            internalTestWeaving(new Man(), isWeavingForChangeTrackingEnabled(), isWeavingForFetchGroupsEnabled(), false);
            internalTestWeaving(new Woman(), isWeavingForChangeTrackingEnabled(), isWeavingForFetchGroupsEnabled(), false);
            internalTestWeaving(new Vegetable(), false, isWeavingForFetchGroupsEnabled(), false);  // serialized
            internalTestWeaving(new VegetablePK(), false, isWeavingForFetchGroupsEnabled(), false);
            internalTestWeaving(new WorldRank(), isWeavingForChangeTrackingEnabled(), isWeavingForFetchGroupsEnabled(), false);
            internalTestWeaving(new Equipment(), isWeavingForChangeTrackingEnabled(), isWeavingForFetchGroupsEnabled(), false);
            internalTestWeaving(new EquipmentCode(), isWeavingForChangeTrackingEnabled(), isWeavingForFetchGroupsEnabled(), false);
            internalTestWeaving(new PartnerLink(), isWeavingForChangeTrackingEnabled(), isWeavingForFetchGroupsEnabled(), false);
        }
    }

    /**
     * Test that the object was weaved.
     */
    public void internalTestWeaving(Object object, boolean changeTracking, boolean fetchGroups, boolean indirection) {
        if (!(object instanceof PersistenceWeaved)) {
            fail("Object not weaved:" + object);
        }
        if (indirection && (!(object instanceof PersistenceWeavedLazy))) {
            fail("Object not weaved for indirection:" + object);
        }
        if (changeTracking && (!(object instanceof ChangeTracker))) {
            fail("Object not weaved for ChangeTracker:" + object);
        }
        ClassDescriptor descriptor = getServerSession().getDescriptor(object);
        if (!descriptor.isAggregateDescriptor()) {
            if (changeTracking != descriptor.getObjectChangePolicy().isAttributeChangeTrackingPolicy()) {
                fail("Descriptor not set to use change tracking policy correctly:" + object);
            }
            if (!(object instanceof PersistenceEntity)) {
                fail("Object not weaved for PersistenceEntity:" + object);
            }
            if (fetchGroups && !(object instanceof FetchGroupTracker)) {
                fail("Object not weaved for FetchGroupTracker:" + object);
            }
        }
    }

    // this test was failing after transaction ailitche_main_6333458_070821
    public void testManyToOnePersistCascadeOnFlush() {
        boolean pass = false;
        EntityManager em = createEntityManager();
        beginTransaction(em);
        try {
            String firstName = "testManyToOneContains";
            Address address = new Address();
            address.setCountry(firstName);
            Employee employee = new Employee();
            employee.setFirstName(firstName);
            em.persist(employee);

            employee.setAddress(address);
            em.flush();

            pass = em.contains(address);
        } finally {
           rollbackTransaction(em);
           closeEntityManager(em);
        }
        if(!pass) {
            fail("em.contains(address) returned false");
        }
    }

    // This test weaving works with over-writing methods in subclasses, and overloading methods.
    public void testOverwrittingAndOverLoadingMethods() {
        EntityManager em = createEntityManager();
        beginTransaction(em);
        try {
            Address address = new Address();
            address.setCity("Ottawa");
            Employee employee = new Employee();
            employee.setAddress(address);
            LargeProject project = new LargeProject();
            project.setTeamLeader(employee);
            em.persist(employee);
            em.persist(project);
            commitTransaction(em);
            closeEntityManager(em);
            em = createEntityManager();
            beginTransaction(em);
            employee = em.find(Employee.class, employee.getId());
            project = em.find(LargeProject.class, project.getId());
            if ((employee.getAddress("Home") == null) || (!employee.getAddress("Home").getCity().equals("Ottawa"))) {
                fail("Get address did not work.");
            }
            employee.setAddress("Toronto");
            if (!employee.getAddress().getCity().equals("Toronto")) {
                fail("Set address did not work.");
            }
            if (project.getTeamLeader() != employee) {
                fail("Get team leader did not work, team is: " + project.getTeamLeader() + " but should be:" + employee);
            }
            em.remove(employee.getAddress());
            em.remove(employee);
            em.remove(project);
        } finally {
            if (isTransactionActive(em)) {
                rollbackTransaction(em);
            }
            closeEntityManager(em);
        }
    }

    // This tests that new objects referenced by new objects are found on commit.
    public void testDiscoverNewReferencedObject() {
        String firstName = "testDiscoverNewReferencedObject";

        // setup: create and persist Employee
        EntityManager em = createEntityManager();
        int employeeId = 0;
        beginTransaction(em);
        try {
            Employee employee = new Employee();
            employee.setFirstName(firstName);
            employee.setLastName("Employee");
            em.persist(employee);
            commitTransaction(em);
            employeeId = employee.getId();
        } finally {
            if(isTransactionActive(em)) {
                rollbackTransaction(em);
            }
            closeEntityManager(em);
        }

        // test: add to the exsisting Employee a new Manager with new Phones
        em = createEntityManager();
        int managerId = 0;
        beginTransaction(em);
        try {
            Employee manager = new Employee();
            manager.setFirstName(firstName);
            manager.setLastName("Manager");

            PhoneNumber phoneNumber1 = new PhoneNumber("home", "613", "1111111");
            manager.addPhoneNumber(phoneNumber1);
            PhoneNumber phoneNumber2 = new PhoneNumber("work", "613", "2222222");
            manager.addPhoneNumber(phoneNumber2);

            Employee employee = em.find(Employee.class, employeeId);
            manager.addManagedEmployee(employee);
            commitTransaction(em);

            managerId = manager.getId();
        } finally {
            if(isTransactionActive(em)) {
                rollbackTransaction(em);
            }
            closeEntityManager(em);
        }

        // verify: were all the new objects written to the data base?
        String errorMsg = "";
        em = createEntityManager();
        try {
            Employee manager = (Employee)em.createQuery("SELECT OBJECT(e) FROM Employee e WHERE e.id = "+managerId).setHint("eclipselink.refresh", "true").getSingleResult();
            if(manager == null) {
                errorMsg = "Manager hasn't been written into the db";
            } else {
                if(manager.getPhoneNumbers().size() != 2) {
                    errorMsg = "Manager has a wrong number of Phones = "+manager.getPhoneNumbers().size()+"; should be 2";
                }
            }
        } finally {
            closeEntityManager(em);
        }

        // clean up: delete Manager - all other object will be cascade deleted.
        em = createEntityManager();
        beginTransaction(em);
        try {
            if(managerId != 0) {
                Employee manager = em.find(Employee.class, managerId);
                em.remove(manager);
            } else if(employeeId != 0) {
                // if Manager hasn't been created - delete Employee
                Employee employee = em.find(Employee.class, employeeId);
                em.remove(employee);
            }
        } finally {
            if(isTransactionActive(em)) {
                rollbackTransaction(em);
            }
            closeEntityManager(em);
        }

        if(errorMsg.length() > 0) {
            fail(errorMsg);
        }
    }

    // bug 6006423: BULK DELETE QUERY FOLLOWED BY A MERGE RETURNS DELETED OBJECT
    public void testBulkDeleteThenMerge() {
        if ((JUnitTestCase.getServerSession()).getPlatform().isSymfoware()) {
            getServerSession().logMessage("Test testBulkDeleteThenMerge skipped for this platform, "
                    + "Symfoware doesn't support UpdateAll/DeleteAll on multi-table objects (see rfe 298193).");
            return;
        }
        if (isOnServer()) {
            // Got transaction timeout on server.
            return;
        }
        String firstName = "testBulkDeleteThenMerge";

        // setup - create Employee
        EntityManager em = createEntityManager();
        beginTransaction(em);
        Employee emp = new Employee();
        emp.setFirstName(firstName);
        emp.setLastName("Original");
        em.persist(emp);
        commitTransaction(em);
        closeEntityManager(em);

        int id = emp.getId();

        // test
        // delete the Employee using bulk delete
        em = createEntityManager();
        beginTransaction(em);
        em.createQuery("DELETE FROM Employee e WHERE e.firstName = '"+firstName+"'").executeUpdate();
        commitTransaction(em);
        closeEntityManager(em);

        // then re-create and merge the Employee using the same pk
        em = createEntityManager();
        beginTransaction(em);
        emp = new Employee();
        emp.setId(id);
        emp.setFirstName(firstName);
        emp.setLastName("New");
        em.merge(emp);
        try {
            commitTransaction(em);
        } finally {
            if (isTransactionActive(em)){
                rollbackTransaction(em);
            }
            closeEntityManager(em);
        }

        // verify
        String errorMsg = "";
        em = createEntityManager();
        // is the right Employee in the cache?
        emp = (Employee)em.createQuery("SELECT OBJECT(e) FROM Employee e WHERE e.id = " + id).getSingleResult();
        if(emp == null) {
            errorMsg = "Cache: Employee is not found; ";
        } else {
            if(!emp.getLastName().equals("New")) {
                errorMsg = "Cache: wrong lastName = "+emp.getLastName()+"; should be New; ";
            }
        }
        // is the right Employee in the db?
        emp = (Employee)em.createQuery("SELECT OBJECT(e) FROM Employee e WHERE e.id = " + id).setHint("eclipselink.refresh", Boolean.TRUE).getSingleResult();
        if(emp == null) {
            errorMsg = errorMsg + "DB: Employee is not found";
        } else {
            if(!emp.getLastName().equals("New")) {
                errorMsg = "DB: wrong lastName = "+emp.getLastName()+"; should be New";
            }
            // clean up in case the employee is in the db
            beginTransaction(em);
            em.remove(emp);
            commitTransaction(em);
        }
        closeEntityManager(em);

        if(errorMsg.length() > 0) {
            fail(errorMsg);
        }
    }

    public void testNativeSequences() {
        ServerSession ss = JUnitTestCase.getServerSession();
        boolean doesPlatformSupportIdentity = ss.getPlatform().supportsIdentity();
        boolean doesPlatformSupportSequenceObjects = ss.getPlatform().supportsSequenceObjects();
        String errorMsg = "";

        // SEQ_GEN_IDENTITY sequence defined by
        // @GeneratedValue(strategy=IDENTITY)
        boolean isIdentity = ss.getPlatform().getSequence("SEQ_GEN_IDENTITY").shouldAcquireValueAfterInsert();
        if(doesPlatformSupportIdentity != isIdentity) {
            errorMsg = "SEQ_GEN_IDENTITY: doesPlatformSupportIdentity = " + doesPlatformSupportIdentity +", but isIdentity = " + isIdentity +"; ";
        }

        // ADDRESS_SEQ sequence defined by
        // @GeneratedValue(generator="ADDRESS_SEQ")
        // @SequenceGenerator(name="ADDRESS_SEQ", allocationSize=25)
        boolean isSequenceObject = !ss.getPlatform().getSequence("ADDRESS_SEQ").shouldAcquireValueAfterInsert();
        if(doesPlatformSupportSequenceObjects != isSequenceObject) {
            errorMsg = errorMsg +"ADDRESS_SEQ: doesPlatformSupportSequenceObjects = " + doesPlatformSupportSequenceObjects +", but isSequenceObject = " + isSequenceObject;
        }

        if(errorMsg.length() > 0) {
            fail(errorMsg);
        }
    }

    /**
     * Test that sequence numbers allocated but unused in the transaction
     * kept after transaction commits
     * in case SequencingCallback used (that happens if TableSequence is used without
     * using sequencing connection pool).
     */
    public void testSequencePreallocationUsingCallbackTest() {
        // setup
        ServerSession ss = getServerSession();
        // make sure the sequence has both preallocation and callback
        // (the latter means not using sequencing connection pool,
        // acquiring values before insert and requiring transaction).
        //if(ss.getSequencingControl().shouldUseSeparateConnection()) {
        //    fail("setup failure: the test requires serverSession.getSequencingControl().shouldUseSeparateConnection()==false");
        //}
        String seqName = ss.getDescriptor(Employee.class).getSequenceNumberName();
        Sequence sequence = getServerSession().getLogin().getSequence(seqName);
        if(sequence.getPreallocationSize() < 2) {
            fail("setup failure: the test requires sequence preallocation size greater than 1");
        }
        if(sequence.shouldAcquireValueAfterInsert()) {
            fail("setup failure: the test requires sequence that acquires value before insert, like TableSequence");
        }
        if(!sequence.shouldUseTransaction()) {
            fail("setup failure: the test requires sequence that uses transaction, like TableSequence");
        }
        // clear all already allocated sequencing values for seqName
        getServerSession().getSequencingControl().initializePreallocated(seqName);

        // test
        EntityManager em = createEntityManager();
        beginTransaction(em);
        Employee emp1 = new Employee();
        emp1.setFirstName("testSequencePreallocation");
        emp1.setLastName("1");
        em.persist(emp1);
        int assignedSequenceNumber = emp1.getId();
        commitTransaction(em);

        // verify
        em = createEntityManager();
        beginTransaction(em);
        Employee emp2 = new Employee();
        emp2.setFirstName("testSequencePreallocation");
        emp2.setLastName("2");
        em.persist(emp2);
        int nextSequenceNumber = emp2.getId();
        // only need nextSequenceNumber, no need to commit
        rollbackTransaction(em);

        // cleanup
        // remove the object that has been created in setup
        em = createEntityManager();
        beginTransaction(em);
        emp1 = em.find(Employee.class, assignedSequenceNumber);
        em.remove(emp1);
        commitTransaction(em);

        // report result
        if(assignedSequenceNumber + 1 != nextSequenceNumber) {
            fail("Transaction that assigned sequence number committed, assignedSequenceNumber = " + assignedSequenceNumber +", but nextSequenceNumber = "+ nextSequenceNumber +"("+Integer.toString(assignedSequenceNumber+1)+" was expected)");
        }
    }

    /**
     * Create a test employee.
     */
    protected Employee createEmployee(String name) {
        EntityManager em = createEntityManager();
        beginTransaction(em);
        Employee employee = new Employee();
        employee.setFirstName(name);
        em.persist(employee);
        commitTransaction(em);
        return employee;
    }

    /**
     * Test getEntityManagerFactory() API
     * tests whether illegalArgumentException is thrown when
     * an entity manager is closed.
     */
    public void testGetEntityManagerFactory() {
        Employee emp = new Employee();
        EntityManager em = createEntityManager();
        try {
            beginTransaction(em);
            emp.setFirstName("test");
            em.persist(emp);
            commitTransaction(em);
            EntityManagerFactory emf = em.getEntityManagerFactory();
            if (emf == null) {
                fail("Factory is null.");
            }
        } finally {
            closeEntityManager(em);
        }
    }

    /**
     * Test getReference() API.
     */
    public void testGetReference() {
        Employee employee = createEmployee("testGetReference");
        int id = employee.getId();
        int version = employee.getVersion();

        EntityManager em = createEntityManager();
        beginTransaction(em);
        employee = em.getReference(Employee.class, id);
        if (!employee.getFirstName().equals("testGetReference")) {
            fail("getReference returned the wrong object");
        }
        commitTransaction(em);
        if (employee.getVersion() != version) {
            fail("fetched object was updated");
        }

        clearCache();

        em = createEntityManager();
        beginTransaction(em);
        employee = em.getReference(Employee.class, id);
        if (employee instanceof FetchGroupTracker) {
            if (((FetchGroupTracker)employee)._persistence_isAttributeFetched("firstName")) {
                fail("getReference fetched object.");
            }
        }
        if (!employee.getFirstName().equals("testGetReference")) {
            fail("getReference returned the wrong object");
        }
        commitTransaction(em);
        if (employee.getVersion() != version) {
            fail("fetched object was updated");
        }

        clearCache();

        em = createEntityManager();
        beginTransaction(em);
        employee = em.find(Employee.class, id);
        if (!employee.getFirstName().equals("testGetReference")) {
            fail("find returned the wrong object");
        }
        commitTransaction(em);

        clearCache();

        List key = new ArrayList();
        key.add(id);
        em = createEntityManager();
        beginTransaction(em);
        employee = em.getReference(Employee.class, key);
        if (!employee.getFirstName().equals("testGetReference")) {
            fail("getReference returned the wrong object");
        }
        commitTransaction(em);

        clearCache();

        em = createEntityManager();
        beginTransaction(em);
        employee = em.find(Employee.class, key);
        if (!employee.getFirstName().equals("testGetReference")) {
            fail("find returned the wrong object");
        }
        commitTransaction(em);
    }

    /**
     * Test getReference() with update.
     */
    public void testGetReferenceUpdate() {
        int id = createEmployee("testGetReference").getId();

        clearCache();

        EntityManager em = createEntityManager();
        beginTransaction(em);
        Employee employee = em.getReference(Employee.class, id);
        employee.setFirstName("changed");
        commitTransaction(em);

        verifyObjectInCacheAndDatabase(employee);
    }

    /**
     * Test adding a new object to a collection.
     */
    public void testCollectionAddNewObjectUpdate() {
        int id = createEmployee("testCollectionAddNew").getId();

        clearCache();

        EntityManager em = createEntityManager();
        beginTransaction(em);
        Employee employee = em.find(Employee.class, id);
        SmallProject project = new SmallProject();
        employee.getProjects().add(project);
        project.getTeamMembers().add(employee);
        commitTransaction(em);


        // 264768: Certain application servers like WebSphere 7 will call em.clear() during commit()
        // in order that the entityManager is cleared before returning the em to their server pool.
        // We will want to verify that the entity is managed before accessing its properties and causing
        // the object to be rebuilt with any non-direct fields uninstantiated.
        // Note: even in this case the entity should still be in the shared cache and database below
        if(em.contains(employee)) {
            verifyObject(project);
            verifyObject(employee);
        }

        clearCache();
        if(em.contains(employee)) {
            verifyObject(project);
            verifyObject(employee);
        }
    }

    /**
     * Test getReference() with bad id.
     */
    public void testBadGetReference() {

        clearCache();

        EntityManager em = createEntityManager();
        Exception caught = null;
        try {
            Employee employee = em.getReference(Employee.class, -123);
            employee.getFirstName();
        } catch (EntityNotFoundException exception) {
            caught = exception;
        }
        if (caught == null) {
            fail("getReference did not throw an error for a bad id");
        }

    }

    /**
     * Test getReference() used in update.
     */
    public void testGetReferenceUsedInUpdate() {
        Employee employee = createEmployee("testGetReference");
        int id = employee.getId();
        int version = employee.getVersion();

        clearCache();

        EntityManager em = createEntityManager();
        beginTransaction(em);
        employee = em.getReference(Employee.class, id);
        if (employee instanceof FetchGroupTracker) {
            if (((FetchGroupTracker)employee)._persistence_isAttributeFetched("firstName")) {
                fail("getReference fetched object.");
            }
        }
        Employee newEmployee = new Employee();
        newEmployee.setFirstName("new");
        newEmployee.setManager(employee);
        em.persist(newEmployee);
        commitTransaction(em);

        if (employee instanceof FetchGroupTracker) {
            if (((FetchGroupTracker)employee)._persistence_isAttributeFetched("firstName")) {
                fail("commit fetched object.");
            }
        }

        // 264768: Certain application servers like WebSphere 7 will call em.clear() during commit()
        // in order that the entityManager is cleared before returning the em to their server pool.
        // We will want to verify that the entity is managed before accessing its properties and causing
        // the object to be rebuilt with any non-direct fields uninstantiated.
        // Note: even in this case the entity should still be in the shared cache and database below
        if(em.contains(employee)) {
            if (employee.getVersion() != version) {
                fail("un-fetched object was updated");
            }
        }

        verifyObjectInCacheAndDatabase(newEmployee);
    }

    public void testClassInstanceConverter(){
        EntityManager em = createEntityManager();
        beginTransaction(em);
        Address add = new Address();
        add.setCity("St. Louis");
        add.setType(new Bungalow());
        em.persist(add);
        commitTransaction(em);
        int assignedSequenceNumber = add.getID();

        em.clear();
        getServerSession().getIdentityMapAccessor().initializeAllIdentityMaps();

        add = em.find(Address.class, assignedSequenceNumber);

        assertTrue("Did not correctly persist a mapping using a class-instance converter", (add.getType() instanceof Bungalow));

        beginTransaction(em);
        add = em.find(Address.class, assignedSequenceNumber);
        em.remove(add);
        commitTransaction(em);
    }

    /**
     * See bug# 210280: verify that the URL encoding for spaces and multibyte chars is handled properly in the EMSetup map lookup
     * UC1 - EM has no spaces or multi-byte chars in name or path
     * UC2 - EM has spaces hex(20) in EM name but not in path
     * UC3/4 are fixed by 210280 - the other UC tests are for regression
     * UC3 - EM has spaces in path but not in the EM name
     * UC4 - EM has spaces in path and EM name
     * UC5 - EM has multi-byte hex(C3A1) chars in EM name but not in path
     * Keep resource with spaces and multibyte chars separate
     * UC6 - EM has multi-byte chars in path but not EM name
     * UC7 - EM has multi-byte chars in path and EM name
     * UC8 - EM has spaces and multi-byte chars in EM name but not in path
     * UC9 - EM has spaces and multi-byte chars in path and EM name
     */
    // UC2 - EM has spaces in EM name but not in path
    public void test210280EntityManagerFromPUwithSpaceInNameButNotInPath() {
        // This EM is defined in a persistence.xml that is off eclipselink-advanced-properties (no URL encoded chars in path)
        privateTest210280EntityManagerWithPossibleSpacesInPathOrName(//
                "A JPAADVProperties pu with spaces in the name", //
                "with a name containing spaces was not found.");
    }

    // UC3 - EM has spaces in path but not in the EM name
    public void test210280EntityManagerFromPUwithSpaceInPathButNotInName() {
        // This EM is defined in a persistence.xml that is off [eclipselink-pu with spaces] (with URL encoded chars in path)
        privateTest210280EntityManagerWithPossibleSpacesInPathOrName(//
                "eclipselink-pu-with-spaces-in-the-path-but-not-the-name", //
                "with a path containing spaces was not found.");
    }

    // UC4 - EM has spaces in the path and name
    public void test210280EntityManagerFromPUwithSpaceInNameAndPath() {
        // This EM is defined in a persistence.xml that is off [eclipselink-pu with spaces] (with URL encoded chars in path)
        privateTest210280EntityManagerWithPossibleSpacesInPathOrName(//
                "eclipselink-pu with spaces in the path and name", //
                "with a path and name both containing spaces was not found.");
    }

    private void privateTest210280EntityManagerWithPossibleSpacesInPathOrName(String puName, String failureMessagePostScript) {
        EntityManager em = null;
        try {
            em = createEntityManager(puName);
        } catch (Exception exception) {
            throw new RuntimeException("A Persistence Unit [" + puName + "] " + failureMessagePostScript, exception);
        } finally {
            if (null != em) {
                closeEntityManager(em);
            }
        }
    }

    public void testConnectionPolicy() {
        internalTestConnectionPolicy(false);
    }

    public void testConnectionPolicySetProperty() {
        internalTestConnectionPolicy(true);
    }

    public void internalTestConnectionPolicy(boolean useSetProperty) {
        // setup
        String errorMsg = "";

        HashMap properties = null;
        if(!useSetProperty) {
            properties = new HashMap();
            properties.put(EntityManagerProperties.JDBC_USER, "em_user");
            properties.put(EntityManagerProperties.JDBC_PASSWORD, "em_password");
            properties.put(EntityManagerProperties.JTA_DATASOURCE, "em_jta_datasource");
            properties.put(EntityManagerProperties.NON_JTA_DATASOURCE, "em_nonjta_datasource");
            properties.put(EntityManagerProperties.EXCLUSIVE_CONNECTION_MODE, ExclusiveConnectionMode.Always);
        }

        // test
        EntityManager em = null;
        boolean isInTransaction = false;
        try {
            // assume that if JTA is used on server then EntityManager is always injected.
            boolean isEmInjected = isOnServer() && getServerSession().getLogin().shouldUseExternalTransactionController();
            if (isEmInjected) {
                em = createEntityManager();
                // In server jta case need a transaction - otherwise the wrapped EntityManagerImpl is not kept.
                beginTransaction(em);
                isInTransaction = true;
                ((EntityManagerImpl)em.getDelegate()).setProperties(properties);
            } else {
                EntityManagerFactory emFactory = getEntityManagerFactory();
                em = emFactory.createEntityManager(properties);
            }
            if(useSetProperty) {
                em.setProperty(EntityManagerProperties.JDBC_USER, "em_user");
                em.setProperty(EntityManagerProperties.JDBC_PASSWORD, "em_password");
                em.setProperty(EntityManagerProperties.JTA_DATASOURCE, "em_jta_datasource");
                em.setProperty(EntityManagerProperties.NON_JTA_DATASOURCE, "em_nonjta_datasource");
                em.setProperty(EntityManagerProperties.EXCLUSIVE_CONNECTION_MODE, ExclusiveConnectionMode.Always);
            }

            // verify
            ClientSession clientSession;
            if (isOnServer()) {
                clientSession = (ClientSession)((EntityManagerImpl)em.getDelegate()).getActivePersistenceContext(null).getParent();
            } else {
                clientSession = (ClientSession)((EntityManagerImpl)em).getActivePersistenceContext(null).getParent();
            }
            if(!clientSession.isExclusiveIsolatedClientSession()) {
                errorMsg += "ExclusiveIsolatedClientSession was expected\n";
            }
            ConnectionPolicy policy = clientSession.getConnectionPolicy();
            if(policy.isPooled()) {
                errorMsg += "NOT pooled policy was expected\n";
            }
            String user = (String)policy.getLogin().getProperty("user");
            if(!user.equals("em_user")) {
                errorMsg += "em_user was expected\n";
            }
            String password = (String)policy.getLogin().getProperty("password");
            if(!password.equals("em_password")) {
                errorMsg += "em_password was expected\n";
            }
            if(! (((DatasourceLogin)policy.getLogin()).getConnector() instanceof JNDIConnector)) {
                errorMsg += "JNDIConnector was expected\n";
            } else {
                JNDIConnector jndiConnector = (JNDIConnector)((DatasourceLogin)policy.getLogin()).getConnector();
                String dataSourceName = jndiConnector.getName();
                if(dataSourceName == null) {
                    errorMsg += "NON null dataSourceName was expected\n";
                } else {
                    if(clientSession.getParent().getLogin().shouldUseExternalTransactionController()) {
                        if(dataSourceName.equals("em_nonjta_datasource")) {
                            errorMsg += "em_jta_datasource was expected\n";
                        }
                    } else {
                        if(dataSourceName.equals("em_jta_datasource")) {
                            errorMsg += "em_nonjta_datasource was expected\n";
                        }
                    }
                }
            }
        } finally {
            // clean-up
            if (isInTransaction) {
                rollbackTransaction(em);
            }
            if(em != null) {
                closeEntityManager(em);
            }
        }

        if(errorMsg.length() > 0) {
            fail(errorMsg);
        }
    }

    /*
     * Added for bug 235340 - parameters in named query are not  transformed when IN is used.
     * Before the fix this used to throw exception.
     */
    public void testConverterIn() {
        EntityManager em = createEntityManager();
        List<Employee> emps = em.createQuery("SELECT e FROM Employee e WHERE e.gender IN (:GENDER1, :GENDER2)").
                        setParameter("GENDER1", Employee.Gender.Male).
                        setParameter("GENDER2", Employee.Gender.Female).
                        getResultList();
        emps.toString();
        closeEntityManager(em);
    }

    // Bug 237281 - ensure we throw the correct exception when trying to persist a non-entity subclass of an entity
    public void testExceptionForPersistNonEntitySubclass(){
        EntityManager em = createEntityManager();
        Exception caughtException = null;
        try{
            beginTransaction(em);
            em.persist(new SuperLargeProject());
        } catch (IllegalArgumentException e){
            caughtException = e;
        } finally {
            rollbackTransaction(em);
            closeEntityManager(em);
        }
        if (caughtException == null){
            fail("Caught an incorrect exception when persisting a non entity.");
        }
    }

    // bug 237281 - ensure seeting InheritancePolicy to allow non-entity subclasses to be persisted as their
    // superclass works
    public void testEnabledPersistNonEntitySubclass() {
        EntityManager em = createEntityManager();
        InheritancePolicy ip = getServerSession().getDescriptor(Project.class).getInheritancePolicy();
        boolean describesNonPersistentSubclasses = ip.getDescribesNonPersistentSubclasses();
        ip.setDescribesNonPersistentSubclasses(true);

        beginTransaction(em);
        SuperLargeProject s1 = new SuperLargeProject("Super 1");
        try {
            em.persist(s1);
        } catch (Exception e) {
            if (isTransactionActive(em)){
                rollbackTransaction(em);
            }
            fail("Persist operation was not cascaded to related non-entity, thrown: " + e);
        } finally {
            rollbackTransaction(em);
            ip.setDescribesNonPersistentSubclasses(describesNonPersistentSubclasses);
            closeEntityManager(em);
        }
    }

    // bug 239505 - Ensure our Embeddables succeed a call to clone
    public void testCloneEmbeddable(){
        EmployeePopulator populator = new EmployeePopulator();
        EmploymentPeriod period = populator.employmentPeriodExample1();

        try {
            period.clone();
        } catch (Exception e){
            fail("Exception thrown when trying to clone an Embeddable: " + e.toString());
        }
    }

    // bug 232555 - NPE setting embedded attributes after persist in woven classes
    public void testEmbeddedNPE() {
        if (isOnServer()) {
            // Close is not used on server.
            return;
        }
        // setup
        // create and persist an Employee
        Employee emp = new Employee();
        emp.setFirstName("testEmbeddedNPE");
        EntityManager em = createEntityManager();
        beginTransaction(em);
        em.persist(emp);
        commitTransaction(em);

        // test
        // add an embedded to the persisted Employee
        EmploymentPeriod period = new EmploymentPeriod(Date.valueOf("2007-01-01"), Date.valueOf("2007-12-31"));
        try {
            // that used to cause NPE
            emp.setPeriod(period);
        } catch (NullPointerException npe) {
            // clean-up
            beginTransaction(em);
            em.remove(emp);
            commitTransaction(em);
            em.close();

            throw npe;
        }

        // update the Employee in the db
        beginTransaction(em);
        em.merge(emp);
        commitTransaction(em);

        // verify
        // make sure that the Employee has been written into the db correctly:
        // clear both em and shared cache
        em.clear();
        clearCache();
        // and re-read it
        Employee readEmp = em.find(Employee.class, emp.getId());
        // should be the same as the original one
        boolean equal = getServerSession().compareObjects(emp, readEmp);

        // clean-up
        if(readEmp != null) {
            beginTransaction(em);
            //readEmp = em.find(Employee.class, emp.getId());
            em.remove(readEmp);
            commitTransaction(em);
        }
        em.close();

        if(!equal) {
            fail("The Employee wasn't updated correctly in the db");
        }
    }

    // Bug 256296: Reconnect fails when session loses connectivity
    static class AcquireReleaseListener extends SessionEventAdapter {
        HashSet<Accessor> acquiredReadConnections = new HashSet();
        HashSet<Accessor> acquiredWriteConnections = new HashSet();
        @Override
        public void postAcquireConnection(SessionEvent event) {
            Accessor accessor = (Accessor)event.getResult();
            Session session = event.getSession();
            if(session.isServerSession()) {
                acquiredReadConnections.add(accessor);
                ((ServerSession)session).log(SessionLog.FINEST, SessionLog.CONNECTION, "AcquireReleaseListener.acquireReadConnection: " + nAcquredReadConnections(), null, accessor, false);
            } else {
                acquiredWriteConnections.add(accessor);
                ((ClientSession)session).log(SessionLog.FINEST, SessionLog.CONNECTION, "AcquireReleaseListener.acquireWriteConnection: " + nAcquredWriteConnections(), null, accessor, false);
            }
        }
        @Override
        public void preReleaseConnection(SessionEvent event) {
            Accessor accessor = (Accessor)event.getResult();
            Session session = event.getSession();
            if(session.isServerSession()) {
                acquiredReadConnections.remove(accessor);
                ((ServerSession)session).log(SessionLog.FINEST, SessionLog.CONNECTION, "AcquireReleaseListener.releaseReadConnection: " + nAcquredReadConnections(), null, accessor, false);
            } else {
                acquiredWriteConnections.remove(accessor);
                ((ClientSession)session).log(SessionLog.FINEST, SessionLog.CONNECTION, "AcquireReleaseListener.releaseWriteConnection: " + nAcquredWriteConnections(), null, accessor, false);
            }
        }
        int nAcquredReadConnections() {
            return acquiredReadConnections.size();
        }
        int nAcquredWriteConnections() {
            return acquiredWriteConnections.size();
        }
        void clear() {
            acquiredReadConnections.clear();
            acquiredWriteConnections.clear();
        }
    }
    public void testEMCloseAndOpen(){
        if (isOnServer()) {
            // Uses DefaultConnector.
            return;
        }

        //Assert.assertFalse("Warning Sybase Driver does not work with DriverWrapper, testEMCloseAndOpen can't run on this platform.",  JUnitTestCase.getServerSession().getPlatform().isSybase());
        if ((JUnitTestCase.getServerSession()).getPlatform().isSymfoware()) {
            getServerSession().logMessage("Test testEMCloseAndOpen skipped for this platform, "
                            + "Symfoware platform doesn't support failover.");
            return;
        }
        else   if ((JUnitTestCase.getServerSession()).getPlatform().isPervasive()) {
            getServerSession().logMessage("Test testEMCloseAndOpen skipped for this platform." );
            return;
        }

        // normally false; set to true for debug output for just this single test
        boolean shouldForceFinest = false;
        int originalLogLevel = -1;

        ServerSession ss = ((JpaEntityManagerFactory)getEntityManagerFactory()).getServerSession();

        // make sure the id hasn't been already used - it will be assigned to a new object (in case sequencing is not used).
        int id = (ss.getNextSequenceNumberValue(Employee.class)).intValue();

        // cache the original driver name and connection string.
        String originalDriverName = ss.getLogin().getDriverClassName();
        String originalConnectionString = ss.getLogin().getConnectionString();

        // the new driver name and connection string to be used by the test
        String newDriverName = DriverWrapper.class.getName();
        String newConnectionString = DriverWrapper.codeUrl(originalConnectionString);

        // setup the wrapper driver
        DriverWrapper.initialize(originalDriverName);

        // The test need to connect with the new driver and connection string.
        // That could be done in JPA:
        //    // close the existing emf
        //    closeEntityManagerFactory();
        //    HashMap properties = new HashMap(JUnitTestCaseHelper.getDatabaseProperties());
        //    properties.put(PersistenceUnitProperties.JDBC_DRIVER, newDriverName);
        //    properties.put(PersistenceUnitProperties.JDBC_URL, newConnectionString);
        //    emf = getEntityManagerFactory(properties);
        // However this only works in case closeEntityManagerFactory disconnects the original ServerSession,
        // which requires the factory to be the only one using the persistence unit.
        // Alternative - and faster - approach is to disconnect the original session directly
        // and then reconnected it with the new driver and connection string.
        ss.logout();
        ss.getLogin().setDriverClassName(newDriverName);
        ss.getLogin().setConnectionString(newConnectionString);
        AcquireReleaseListener listener = new AcquireReleaseListener();
        ss.getEventManager().addListener(listener);
        if(shouldForceFinest) {
            if(ss.getLogLevel() != SessionLog.FINEST) {
                originalLogLevel = ss.getLogLevel();
                ss.setLogLevel(SessionLog.FINEST);
            }
        }
        ss.login();

        String errorMsg = "";
        // test several configurations:
        // all exclusive connection modes
        String[] exclusiveConnectionModeArray = new String[]{ExclusiveConnectionMode.Transactional, ExclusiveConnectionMode.Isolated, ExclusiveConnectionMode.Always};

        // Workaround for Bug 309881 - problems with CallQueryMechanism.prepareCall method
        // Because of this bug em.find ignores QueryHints.JDBC_TIMEOUT,
        // have to set it directly into the Descriptor's ReadObjectQuery.
        // This should be removed from the test after the bug is fixed.
        ReadObjectQuery employeeFindQuery = ss.getDescriptor(Employee.class).getQueryManager().getReadObjectQuery();
        int originalQueryTimeout = employeeFindQuery.getQueryTimeout();
        if(originalQueryTimeout > 0) {
            ss.setQueryTimeoutDefault(0);
            employeeFindQuery.setQueryTimeout(0);
            // The same bug 309881 requires the query to be reprepaired for queryTimeOut to be set on its call
            employeeFindQuery.setIsPrepared(false);
            employeeFindQuery.checkPrepare(ss, null);
        }

        // currently reconnection is not attempted if query time out is not zero.
        HashMap noTimeOutHint = new HashMap(1);
        noTimeOutHint.put(QueryHints.JDBC_TIMEOUT, 0);
        try {

            for(int i=0; i<3; i++) {
                String exclusiveConnectionMode = exclusiveConnectionModeArray[i];
                for(int j=0; j<2; j++) {
                    // either using or not using sequencing
                    boolean useSequencing = (j==0);
                    ss.log(SessionLog.FINEST, SessionLog.CONNECTION, "testEMCloseAndOpen: " + (useSequencing ? "sequencing" : "no sequencing"), null, null, false);
                    HashMap emProperties = new HashMap(1);
                    emProperties.put(EntityManagerProperties.EXCLUSIVE_CONNECTION_MODE, exclusiveConnectionMode);
                    EntityManager em = createEntityManager(emProperties);

                    em.find(Employee.class, 1, noTimeOutHint);
                    Employee emp = null;
                    boolean hasUnexpectedlyCommitted = false;
                    try{
                        em.getTransaction().begin();

                        // imitate disconnecting from network:
                        // driver's connect method and any method on any connection will throw SQLException
                        ss.log(SessionLog.FINEST, SessionLog.CONNECTION, "testEMCloseAndOpen: DriverWrapper.breakDriver(); DriverWrapper.breakOldConnections();", null, null, false);
                        DriverWrapper.breakDriver();
                        DriverWrapper.breakOldConnections();

                        emp = new Employee();
                        if(!useSequencing) {
                            emp.setId(id);
                        }
                        em.persist(emp);
                        em.getTransaction().commit();

                        // should never get here - all connections should be broken.
                        hasUnexpectedlyCommitted = true;
                        errorMsg += "useSequencing = " + useSequencing + "; exclusiveConnectionMode = " + exclusiveConnectionMode + ": Commit has unexpectedly succeeded - should have failed because all connections broken. driver = " + ss.getLogin().getDriverClassName() + "; url = " + ss.getLogin().getConnectionString();
                    } catch (Exception e){
                        // expected exception - connection is invalid and cannot be reconnected.
                        if(em.getTransaction().isActive()) {
                            em.getTransaction().rollback();
                        }
                    }
                    closeEntityManager(em);

                    // verify - all connections should be released
                    String localErrorMsg = "";
                    if(listener.nAcquredWriteConnections() > 0) {
                        localErrorMsg += "writeConnection not released; ";
                    }
                    if(listener.nAcquredReadConnections() > 0) {
                        localErrorMsg += "readConnection not released; ";
                    }
                    if(localErrorMsg.length() > 0) {
                        localErrorMsg = exclusiveConnectionMode + " useSequencing="+useSequencing + ": " + localErrorMsg;
                        errorMsg += localErrorMsg;
                        listener.clear();
                    }

                    // imitate  reconnecting to network:
                    // driver's connect method will now work, all newly acquired connections will work, too;
                    // however the old connections cached in the connection pools are still invalid.
                    DriverWrapper.repairDriver();
                    ss.log(SessionLog.FINEST, SessionLog.CONNECTION, "testEMCloseAndOpen: DriverWrapper.repairDriver();", null, null, false);

                    boolean failed = true;
                    try {
                        em = createEntityManager();
                        em.find(Employee.class, 1);
                        if(!hasUnexpectedlyCommitted) {
                            em.getTransaction().begin();
                            emp = new Employee();
                            if(!useSequencing) {
                                emp.setId(id);
                            }
                            em.persist(emp);
                            em.getTransaction().commit();
                            failed = false;
                        }
                    } finally {
                        if(failed) {
                            // This should not happen
                            if(em.getTransaction().isActive()) {
                                em.getTransaction().rollback();
                            }
                            closeEntityManager(em);

                            if(errorMsg.length() > 0) {
                                ss.log(SessionLog.FINEST, SessionLog.CONNECTION, "testEMCloseAndOpen: errorMsg: " + "\n" + errorMsg, null, null, false);
                            }
                        }
                    }

                    // clean-up
                    // remove the inserted object
                    em.getTransaction().begin();
                    em.remove(emp);
                    em.getTransaction().commit();
                    closeEntityManager(em);
                }
            }

        } finally {

            // Workaround for Bug 309881 - problems with CallQueryMechanism.prepareCall method
            // Because of this bug em.find ignores QueryHints.JDBC_TIMEOUT,
            // have to set it directly into the Descriptor's ReadObjectQuery.
            // This should be removed from the test after the bug is fixed.
            if(originalQueryTimeout > 0) {
                ss.setQueryTimeoutDefault(originalQueryTimeout);
                employeeFindQuery.setQueryTimeout(originalQueryTimeout);
                // The same bug 309881 requires the query to be reprepaired for queryTimeOut to be set on its call
                employeeFindQuery.setIsPrepared(false);
                employeeFindQuery.checkPrepare(ss, null);
            }
            // clear the driver wrapper
            DriverWrapper.clear();

            // reconnect the session using the original driver and connection string
            ss.getEventManager().removeListener(listener);
            ss.logout();
            if(originalLogLevel >= 0) {
                ss.setLogLevel(originalLogLevel);
            }
            ss.getLogin().setDriverClassName(originalDriverName);
            ss.getLogin().setConnectionString(originalConnectionString);
            ss.login();

            if(errorMsg.length() > 0) {
                fail(errorMsg);
            }
        }
    }

    // Bug 256284: Closing an EMF where the database is unavailable results in deployment exception on redeploy
    public void testEMFactoryCloseAndOpen(){
        if (isOnServer()) {
            // Uses DefaultConnector.
            return;
        }
        //Assert.assertFalse("Warning Sybase Driver does not work with DriverWrapper, testEMCloseAndOpen can't run on this platform.",  JUnitTestCase.getServerSession().getPlatform().isSybase());

        ServerSession ss = ((JpaEntityManagerFactory)getEntityManagerFactory()).getServerSession();

        // cache the driver name
        String driverName = ss.getLogin().getDriverClassName();
        String originalConnectionString = ss.getLogin().getConnectionString();

        // disconnect the session
        closeEntityManagerFactory();

        // setup the wrapper driver
        DriverWrapper.initialize(driverName);

        // connect the session using the wrapper driver
        HashMap properties = new HashMap(JUnitTestCaseHelper.getDatabaseProperties());
        properties.put(PersistenceUnitProperties.JDBC_DRIVER, DriverWrapper.class.getName());
        properties.put(PersistenceUnitProperties.JDBC_URL, DriverWrapper.codeUrl(originalConnectionString));
        getEntityManagerFactory(properties);

        // this connects the session
        EntityManager em = createEntityManager();

        // imitate disconnecting from network:
        // driver's connect method and any method on any connection will throw SQLException
        DriverWrapper.breakDriver();
        DriverWrapper.breakOldConnections();

        // close factory
        try {
            closeEntityManagerFactory();
        } finally {
            // clear the driver wrapper
            DriverWrapper.clear();
        }

        String errorMsg = "";
        //reconnect the session
        em = createEntityManager();
        //verify connections
        Iterator<ConnectionPool> itPools = ((EntityManagerImpl)em).getServerSession().getConnectionPools().values().iterator();
        while (itPools.hasNext()) {
            ConnectionPool pool = itPools.next();
            int disconnected = 0;
            for (int i=0; i < pool.getConnectionsAvailable().size(); i++) {
                if (!(pool.getConnectionsAvailable().get(i)).isConnected()) {
                    disconnected++;
                }
            }
            if (disconnected > 0) {
                errorMsg += pool.getName() + " has " + disconnected + " connections; ";
            }
        }
        if (errorMsg.length() > 0) {
            fail(errorMsg);
        }
    }

    public void testEMFTargetServerEnforcing() {
        // the test requires passing properties to createEMF or createContainerEMF method.
        if (isOnServer()) {
            return;
        }

        EntityManagerFactory emf = null;
        try {
            System.setProperty(SystemProperties.ENFORCE_TARGET_SERVER, "true");
            Map<String, String> properties = new HashMap<>(JUnitTestCaseHelper.getDatabaseProperties());
            properties.put(PersistenceUnitProperties.TARGET_SERVER, Platform.class.getName());
            properties.put(PersistenceUnitProperties.SESSION_NAME, "dummy-default-session");
            PersistenceProvider provider = new PersistenceProvider();
            JPAInitializer initializer = provider.getInitializer(getPersistenceUnitName(), properties);
            SEPersistenceUnitInfo sePUImpl = initializer.findPersistenceUnitInfo(getPersistenceUnitName(), properties);
            emf = provider.createContainerEntityManagerFactory(sePUImpl, properties);
            ServerPlatform server = ((JpaEntityManagerFactory)emf).getServerSession().getServerPlatform();
            assertNotNull(server);
            assertFalse("server should be overridden", server instanceof Platform);
        } finally {
            System.clearProperty(SystemProperties.ENFORCE_TARGET_SERVER);
            if (emf != null) {
                emf.close();
            }
        }
    }

    // Bug 332683 - Problems with ClientSession connections
    // testPostAcquirePreReleaseEvents tests verifies that postAcquireConnection and preReleaseConnection events are risen correctly.
    // The test is run in two configurations: with Internal and External connection pools.
    // Each test loops through several modes, the mode is a cartesian product of the following 3 choices:
    //    pooled  vs  non-pooled modes;
    //    ExclusiveConnectionModes: Transactional  vs  Isolated  vs  Always;
    //    persist and commit  vs   read, begin transaction, persist, commit  vs  uow.beginEarlyTransaction, persist, commit.
    static class AcquireRepair_ReleaseBreak_Listener extends SessionEventAdapter {
        HashSet<Accessor> acquiredConnections = new HashSet();
        @Override
        public void postAcquireConnection(SessionEvent event) {
            Accessor accessor = (Accessor)event.getResult();
            if(acquiredConnections.contains(accessor)) {
                ((AbstractSession)event.getSession()).log(SessionLog.FINEST, SessionLog.CONNECTION, "AcquireRepair_ReleaseBreak_Listener.postAcquireConnection: risen two or more times in a row;", null, accessor, false);
                throw new RuntimeException("AcquireRepair_ReleaseBreak_Listener.postAcquireConnection: risen two or more times in a row");
            } else {
                acquiredConnections.add(accessor);
            }
            ((AbstractSession)event.getSession()).log(SessionLog.FINEST, SessionLog.CONNECTION, "AcquireRepair_ReleaseBreak_Listener.postAcquireConnection: repairConnection;", null, accessor, false);
            ((ConnectionWrapper)accessor.getConnection()).repairConnection();
        }
        @Override
        public void preReleaseConnection(SessionEvent event) {
            Accessor accessor = (Accessor)event.getResult();
            if(!acquiredConnections.contains(accessor)) {
                ((AbstractSession)event.getSession()).log(SessionLog.FINEST, SessionLog.CONNECTION, "AcquireRepair_ReleaseBreak_Listener.preReleaseConnection: postAcquireConnection has not been risen;", null, accessor, false);
                throw new RuntimeException("AcquireRepair_ReleaseBreak_Listener.preReleaseConnection: postAcquireConnection has not been risen");
            } else {
                acquiredConnections.remove(accessor);
            }
            ((AbstractSession)event.getSession()).log(SessionLog.FINEST, SessionLog.CONNECTION, "AcquireRepair_ReleaseBreak_Listener.preReleaseConnection: breakConnection;", null, accessor, false);
            ((ConnectionWrapper)accessor.getConnection()).breakConnection();
        }
        public boolean hasAcquiredConnections() {
            return !acquiredConnections.isEmpty();
        }
    }
    public void testPostAcquirePreReleaseEvents_InternalConnectionPool() {
        internalTestPostAcquirePreReleaseEvents(false);
    }
    public void testPostAcquirePreReleaseEvents_ExternalConnectionPool() {
        internalTestPostAcquirePreReleaseEvents(true);
    }
    public void internalTestPostAcquirePreReleaseEvents(boolean useExternalConnectionPool){
        if (isOnServer()) {
            // Uses DefaultConnector.
            return;
        }

        ServerSession ss = ((JpaEntityManagerFactory)getEntityManagerFactory()).getServerSession();

        //Assert.assertFalse("Warning Sybase Driver does not work with DriverWrapper, testPostAcquirePreReleaseEvents can't run on this platform.",  ss.getPlatform().isSybase());
        if (ss.getPlatform().isSymfoware()) {
            getServerSession().logMessage("Test testPostAcquirePreReleaseEvents skipped for this platform, "
                            + "Symfoware platform doesn't support failover.");
            return;
        }

        // normally false; set to true for debug output for just this single test
        boolean shouldForceFinest = false;
        int originalLogLevel = -1;

        // cache the original driver name and connection string.
        String originalDriverName = ss.getLogin().getDriverClassName();
        String originalConnectionString = ss.getLogin().getConnectionString();
        // cache original connector for external connection pool case
        Connector originalConnector = ss.getLogin().getConnector();

        // the new driver name and connection string to be used by the test
        String newDriverName = DriverWrapper.class.getName();
        String newConnectionString = DriverWrapper.codeUrl(originalConnectionString);

        // setup the wrapper driver
        DriverWrapper.initialize(originalDriverName);

        // The test need to connect with the new driver and connection string.
        // That could be done in JPA:
        //    // close the existing emf
        //    closeEntityManagerFactory();
        //    HashMap properties = new HashMap(JUnitTestCaseHelper.getDatabaseProperties());
        //    properties.put(PersistenceUnitProperties.JDBC_DRIVER, newDriverName);
        //    properties.put(PersistenceUnitProperties.JDBC_URL, newConnectionString);
        //    emf = getEntityManagerFactory(properties);
        // However this only works in case closeEntityManagerFactory disconnects the original ServerSession,
        // which requires the factory to be the only one using the persistence unit.
        // Alternative - and faster - approach is to disconnect the original session directly
        // and then reconnected it with the new driver and connection string.
        ss.logout();
        if(useExternalConnectionPool) {
            ss.getLogin().setConnector(new JNDIConnector(new DataSourceImpl(null, newConnectionString, null, null)));
            ss.getLogin().useExternalConnectionPooling();
        } else {
            ss.getLogin().setDriverClassName(newDriverName);
            ss.getLogin().setConnectionString(newConnectionString);
        }
        if(shouldForceFinest) {
            if(ss.getLogLevel() != SessionLog.FINEST) {
                originalLogLevel = ss.getLogLevel();
                ss.setLogLevel(SessionLog.FINEST);
            }
        }
        // switch off reconnection
        boolean originalIsConnectionHealthValidatedOnError = ss.getLogin().isConnectionHealthValidatedOnError();
        ss.getLogin().setConnectionHealthValidatedOnError(false);

        // Using DriverWrapper the listener will repair connection on postAcquireConnection and break it on preReleaseConnection event.
        // Also the listener will verify that neither postAcquireConnection nor preReleaseConnection events not called two in a row.
        AcquireRepair_ReleaseBreak_Listener listener = new AcquireRepair_ReleaseBreak_Listener();
        ss.getEventManager().addListener(listener);

        // Driver's connect method will still work, however any method called on any acquired connection will throw SQLException.
        // On postAcquireConnection connection will be repaired; on preReleaseConnection - broken again.
        ss.log(SessionLog.FINEST, SessionLog.CONNECTION, "testPostAcquirePreReleaseEvents: DriverWrapper.breakOldConnections(); DriverWrapper.breakNewConnections();", null, null, false);
        DriverWrapper.breakOldConnections();
        DriverWrapper.breakNewConnections();

        ss.login();

        // test several configurations:
        // all exclusive connection modes
        String[] exclusiveConnectionModeArray = new String[]{ExclusiveConnectionMode.Transactional, ExclusiveConnectionMode.Isolated, ExclusiveConnectionMode.Always};

        // Normally the user wishing to use not pooled connection would specify user and password properties (and possibly db url, too).
        // However if these properties have the same values that those in the logging then no non pooled connection is created and the pooled one used instead.
        // In the test we must use the same user as already in the session login (don't know any others) that forces usage of ConnectionPolicy property.
        ConnectionPolicy connectionPolicy = (ConnectionPolicy)ss.getDefaultConnectionPolicy().clone();
        connectionPolicy.setLogin(ss.getLogin());
        connectionPolicy.setPoolName(null);

        try {
            HashMap emProperties = new HashMap();
            String mode, pooled = "", exclusiveConnectionMode;
            for(int k=0; k<2; k++) {
                if(k==1) {
                    //use non pooled connections
                    pooled = "non pooled; ";
                    emProperties.put(EntityManagerProperties.CONNECTION_POLICY, connectionPolicy);
                }
                for(int i=0; i<exclusiveConnectionModeArray.length; i++) {
                    exclusiveConnectionMode = exclusiveConnectionModeArray[i];
                    for(int j=0; j<3; j++) {
                        // either beginning early transaction or not
                        boolean shouldBeginEarlyTransaction = (j==2);
                        boolean shouldReadBeforeTransaction = (j==1);
                        mode = pooled + exclusiveConnectionMode + (shouldBeginEarlyTransaction ? "; beginEarlyTransaction" : "") + (shouldReadBeforeTransaction ? "; readBeforeTransaction" : "");
                        ss.log(SessionLog.FINEST, SessionLog.CONNECTION, "testPostAcquirePreReleaseEvents: " + mode, null, null, false);
                        emProperties.put(EntityManagerProperties.EXCLUSIVE_CONNECTION_MODE, exclusiveConnectionMode);
                        EntityManager em = createEntityManager(emProperties);

                        if(shouldReadBeforeTransaction) {
                            em.find(Employee.class, 1);
                        }
                        Employee emp = null;
                        try{
                            em.getTransaction().begin();

                            if(shouldBeginEarlyTransaction) {
                                em.unwrap(UnitOfWorkImpl.class).beginEarlyTransaction();
                            }

                            emp = new Employee();
                            emp.setFirstName("testPostAcquirePreReleaseEvents");
                            em.persist(emp);
                            em.getTransaction().commit();
                        } finally {
                            // expected exception - connection is invalid and cannot be reconnected.
                            if(em.getTransaction().isActive()) {
                                em.getTransaction().rollback();
                            }
                            closeEntityManager(em);
                        }

                        if(listener.hasAcquiredConnections()) {
                            fail(mode + " connection was not passed to preReleaseConnection event");
                        }
                    }
                }
            }

        } finally {
            // clear the driver wrapper
            DriverWrapper.clear();

            // reconnect the session using the original driver and connection string
            ss.getEventManager().removeListener(listener);
            // clean-up
            // remove the inserted object
            EntityManager em = createEntityManager();
            em.getTransaction().begin();
            try {
                em.createQuery("DELETE FROM Employee e WHERE e.firstName = 'testPostAcquirePreReleaseEvents'");
                em.getTransaction().commit();
            } finally {
                if(em.getTransaction().isActive()) {
                    em.getTransaction().rollback();
                }
                closeEntityManager(em);

                ss.logout();
                if(originalLogLevel >= 0) {
                    ss.setLogLevel(originalLogLevel);
                }
                if(useExternalConnectionPool) {
                    ss.getLogin().setConnector(originalConnector);
                    ss.getLogin().dontUseExternalConnectionPooling();
                } else {
                    ss.getLogin().setDriverClassName(originalDriverName);
                    ss.getLogin().setConnectionString(originalConnectionString);
                }
                ss.getLogin().setConnectionHealthValidatedOnError(originalIsConnectionHealthValidatedOnError);
                ss.login();
            }
        }
    }

    /**
     * Tests that queries will be re-executed if a query fails from a dead connection.
     */
    public void testDeadConnectionFailover(){
        if (isOnServer()) {
            // Uses DefaultConnector.
            return;
        }

        if (JUnitTestCase.getServerSession().getPlatform().isSymfoware() || JUnitTestCase.getServerSession().getPlatform().isSybase()) {
            warning("Test testDeadConnectionFailover skipped for this platform, Sybase, Symfoware platform doesn't support failover.");
            return;
        }

        ServerSession server = ((JpaEntityManagerFactory)getEntityManagerFactory()).getServerSession();

        // cache the original driver name and connection string.
        String originalDriverName = server.getLogin().getDriverClassName();
        String originalConnectionString = server.getLogin().getConnectionString();

        // the new driver name and connection string to be used by the test
        String newDriverName = DriverWrapper.class.getName();
        String newConnectionString = DriverWrapper.codeUrl(originalConnectionString);

        // setup the wrapper driver
        DriverWrapper.initialize(originalDriverName);

        server.logout();
        server.getLogin().setDriverClassName(newDriverName);
        server.getLogin().setConnectionHealthValidatedOnError(true);
        server.getLogin().setConnectionString(newConnectionString);
        server.login();
        try {
            EntityManager em = createEntityManager();
            em.createQuery("Select e from Employee e").getResultList();
            em.getTransaction().begin();
            em.persist(new Employee());
            em.getTransaction().commit();
            // test several configurations:
            // all exclusive connection modes
            String[] exclusiveConnectionModes = new String[]{ExclusiveConnectionMode.Transactional, ExclusiveConnectionMode.Isolated, ExclusiveConnectionMode.Always};
            for (String exclusiveConnectionMode : exclusiveConnectionModes) {
                try {
                    HashMap emProperties = new HashMap(1);
                    emProperties.put(EntityManagerProperties.EXCLUSIVE_CONNECTION_MODE, exclusiveConnectionMode);
                    em = createEntityManager(emProperties);
                    List<Employee> employees = em.createQuery("Select e from Employee e").getResultList();
                    DriverWrapper.breakOldConnections();
                    List<Employee> employees2 = em.createQuery("Select e from Employee e").getResultList();
                    if (employees.size() != employees2.size()) {
                        fail("Query results not the same after failure.");
                    }
                    DriverWrapper.breakOldConnections();
                    em.getTransaction().begin();
                    em.persist(new Employee());
                    DriverWrapper.breakOldConnections();
                    em.getTransaction().commit();
                    em.getTransaction().begin();
                    em.persist(new Employee());
                    em.flush();
                    DriverWrapper.breakOldConnections();
                    boolean failed = false;
                    try {
                        em.getTransaction().commit();
                    } catch (Exception shouldFail) {
                        failed = true;
                    }
                    if (!failed) {
                        fail("Retry should not work in a transaction.");
                    }
                } catch (Exception failed) {
                    fail("Retry did not work, mode:" + exclusiveConnectionMode + " error:" + failed);
                } finally {
                    try {
                        em.close();
                    } catch (Exception ignore) {}
                }
            }
        } finally {
            // clear the driver wrapper
            DriverWrapper.clear();

            // reconnect the session using the original driver and connection string
            server.logout();
            server.getLogin().setDriverClassName(originalDriverName);
            server.getLogin().setConnectionString(originalConnectionString);
            server.login();
        }
    }


    /**
     * Tests that a dead connection pool can fail over.
     */
    public void testDeadPoolFailover(){
        if (isOnServer()) {
            // Uses DefaultConnector.
            return;
        }

        if (JUnitTestCase.getServerSession().getPlatform().isSymfoware() || JUnitTestCase.getServerSession().getPlatform().isSybase()) {
            warning("Test testDeadConnectionFailover skipped for this platform, Sybase, Symfoware platform doesn't support failover.");
            return;
        }

        ServerSession server = ((JpaEntityManagerFactory)getEntityManagerFactory()).getServerSession();

        // cache the original driver name and connection string.
        DatabaseLogin originalLogin = (DatabaseLogin)server.getLogin().clone();

        // the new driver name and connection string to be used by the test
        String newDriverName = DriverWrapper.class.getName();
        String newConnectionString = DriverWrapper.codeUrl(originalLogin.getConnectionString());

        // setup the wrapper driver
        DriverWrapper.initialize(originalLogin.getDriverClassName());

        server.logout();
        server.getLogin().setDriverClassName(newDriverName);
        server.getLogin().setConnectionHealthValidatedOnError(true);
        server.getLogin().setConnectionString(newConnectionString);
        server.addConnectionPool("backup", originalLogin, 2, 4);
        server.getDefaultConnectionPool().addFailoverConnectionPool("backup");
        server.getReadConnectionPool().addFailoverConnectionPool("backup");
        server.login();
        try {
            EntityManager em = createEntityManager();
            em.createQuery("Select e from Employee e").getResultList();
            em.getTransaction().begin();
            em.persist(new Employee());
            em.getTransaction().commit();
            // test several configurations:
            // all exclusive connection modes
            String[] exclusiveConnectionModes = new String[]{ExclusiveConnectionMode.Transactional, ExclusiveConnectionMode.Isolated, ExclusiveConnectionMode.Always};
            for (String exclusiveConnectionMode : exclusiveConnectionModes) {
                try {
                    HashMap emProperties = new HashMap(1);
                    emProperties.put(EntityManagerProperties.EXCLUSIVE_CONNECTION_MODE, exclusiveConnectionMode);
                    em = createEntityManager(emProperties);
                    List<Employee> employees = em.createQuery("Select e from Employee e").getResultList();
                    DriverWrapper.breakAll();
                    List<Employee> employees2 = em.createQuery("Select e from Employee e").getResultList();
                    if (employees.size() != employees2.size()) {
                        fail("Query results not the same after failure.");
                    }
                    em.getTransaction().begin();
                    em.persist(new Employee());
                    em.getTransaction().commit();
                    em.getTransaction().begin();
                    em.persist(new Employee());
                    em.flush();
                    em.getTransaction().commit();
                } catch (Exception failed) {
                    fail("Retry did not work, mode:" + exclusiveConnectionMode + " error:" + failed);
                } finally {
                    try {
                        em.close();
                    } catch (Exception ignore) {}
                }
            }
        } finally {
            // clear the driver wrapper
            DriverWrapper.clear();

            // reconnect the session using the original driver and connection string
            server.logout();
            server.getConnectionPools().remove("backup");
            server.getDefaultConnectionPool().setFailoverConnectionPools(new ArrayList());
            server.getReadConnectionPool().setFailoverConnectionPools(new ArrayList());
            server.getLogin().setDriverClassName(originalLogin.getDriverClassName());
            server.getLogin().setConnectionString(originalLogin.getConnectionString());
            server.login();
        }
    }

    /**
     * This test ensures that the eclipselink.batch query hint works. It tests
     * two things.
     *
     * 1. That the batch read attribute is properly added to the queyr 2. That
     * the query will execute
     *
     * It does not do any verification that the batch reading feature actually
     * works. That is left for the batch reading testing to do.
     */
    public void testForUOWInSharedCacheWithBatchQueryHint() {
        if (isOnServer()) {
            // Can not unwrap on WLS.
            return;
        }

        int id1 = 0;
        EntityManager em = createEntityManager();
        beginTransaction(em);

        Employee manager = new Employee();
        manager.setFirstName("Marvin");
        manager.setLastName("Malone");
        PhoneNumber number = new PhoneNumber("cell", "613", "888-8888");
        manager.addPhoneNumber(number);
        number = new PhoneNumber("home", "613", "888-8880");
        manager.addPhoneNumber(number);
        em.persist(manager);
        id1 = manager.getId();

        Employee emp = new Employee();
        emp.setFirstName("Melvin");
        emp.setLastName("Malone");
        emp.setManager(manager);
        manager.addManagedEmployee(emp);
        number = new PhoneNumber("cell", "613", "888-9888");
        emp.addPhoneNumber(number);
        number = new PhoneNumber("home", "613", "888-0880");
        emp.addPhoneNumber(number);
        em.persist(emp);

        emp = new Employee();
        emp.setFirstName("David");
        emp.setLastName("Malone");
        emp.setManager(manager);
        manager.addManagedEmployee(emp);
        number = new PhoneNumber("cell", "613", "888-9988");
        emp.addPhoneNumber(number);
        number = new PhoneNumber("home", "613", "888-0980");
        emp.addPhoneNumber(number);
        em.persist(emp);

        commitTransaction(em);
        closeEntityManager(em);
        clearCache();

        // org.eclipse.persistence.jpa.JpaQuery query =
        // (org.eclipse.persistence.jpa.JpaQuery)em.createQuery("SELECT e FROM Employee e WHERE e.lastName = 'Malone' order by e.firstName");
        em = createEntityManager();
        beginTransaction(em);
        org.eclipse.persistence.jpa.JpaQuery query = (org.eclipse.persistence.jpa.JpaQuery) em.createQuery("SELECT e FROM Employee e WHERE e.lastName = 'Malone' order by e.firstName");
        query.setHint(QueryHints.BATCH, "e.phoneNumbers");

        List resultList = query.getResultList();
        emp = (Employee) resultList.get(0);
        emp.setFirstName("somethingelse" + System.currentTimeMillis());

        // execute random other query
        em.createQuery("SELECT e FROM Employee e WHERE e.lastName = 'Malone'").getResultList();
        ((Employee) resultList.get(1)).getPhoneNumbers().hashCode();

        commitTransaction(em);
        try {
            emp = (Employee) JpaHelper.getEntityManager(em).getServerSession().getIdentityMapAccessor().getFromIdentityMap(emp);
            assertNotNull("Error, phone numbers is empty.  Not Batch Read", emp.getPhoneNumbers());
            assertFalse("PhoneNumbers was empty.  This should not be the case as the test created phone numbers", emp.getPhoneNumbers().isEmpty());
            assertTrue("Phonee numbers was not an indirectList", emp.getPhoneNumbers() instanceof IndirectList);
            assertNotNull("valueholder was null in triggered batch attribute", ((IndirectList) emp.getPhoneNumbers()).getValueHolder());
            QueryBasedValueHolder bvh = (QueryBasedValueHolder) ((IndirectList) emp.getPhoneNumbers()).getValueHolder();
            if (!usesSOP()) {
                if (!(bvh instanceof BatchValueHolder)) {
                    fail("BatchValueHolder was expected, instead got " + bvh);
                }
            }
            if (bvh.getQuery() != null && bvh.getQuery().getSession() != null && bvh.getQuery().getSession().isUnitOfWork()) {
                fail("In Shared Cache a UOW was set within a BatchValueHolder's query object");
            }
            closeEntityManager(em);
        } finally {
            em = createEntityManager();
            beginTransaction(em);
            emp = em.find(Employee.class, id1);
            Iterator it = emp.getManagedEmployees().iterator();
            while (it.hasNext()) {
                Employee managedEmp = (Employee) it.next();
                it.remove();
                managedEmp.setManager(null);
                em.remove(managedEmp);
            }
            em.remove(emp);
            commitTransaction(em);
        }
    }

    public void testIsLoaded(){
        EntityManagerFactory emf = getEntityManagerFactory();
        EntityManager em = createEntityManager();
        beginTransaction(em);
        try{
            Employee emp = new Employee();
            emp.setFirstName("Abe");
            emp.setLastName("Jones");
            Address addr = new Address();
            addr.setCity("Palo Alto");
            emp.setAddress(addr);

            PhoneNumber pn = new PhoneNumber();
            pn.setNumber("1234456");
            pn.setType("Home");
            emp.addPhoneNumber(pn);
            pn.setOwner(emp);
            em.persist(emp);
            em.flush();

            em.clear();
            clearCache();

            emp = em.find(Employee.class, emp.getId());
            PersistenceUnitUtil util = emf.getPersistenceUnitUtil();
            assertTrue("PersistenceUnitUtil says employee is not loaded when it is.", util.isLoaded(emp));
        } finally {
            rollbackTransaction(em);
        }
    }

    public void testIsLoadedAttribute(){
        EntityManagerFactory emf = getEntityManagerFactory();
        EntityManager em = createEntityManager();
        beginTransaction(em);
        try{
            Employee emp = new Employee();
            emp.setFirstName("Abe");
            emp.setLastName("Jones");
            Address addr = new Address();
            addr.setCity("Palo Alto");
            emp.setAddress(addr);

            PhoneNumber pn = new PhoneNumber();
            pn.setNumber("1234456");
            pn.setType("Home");
            emp.addPhoneNumber(pn);
            pn.setOwner(emp);

            SmallProject project = new SmallProject();
            project.setName("Utility Testing");
            project.addTeamMember(emp);
            emp.addProject(project);
            em.persist(emp);
            em.flush();

            em.clear();
            clearCache();

            emp = em.find(Employee.class, emp.getId());
            PersistenceUnitUtil util = emf.getPersistenceUnitUtil();
            if (emp instanceof PersistenceWeaved){
                assertFalse("PersistenceUnitUtil says address is loaded when it is not", util.isLoaded(emp, "address"));
            } else {
                assertTrue("Non-weaved PersistenceUnitUtil says address is not loaded", util.isLoaded(emp, "address"));
            }
            assertFalse("PersistenceUnitUtil says projects is loaded when it is not", util.isLoaded(emp, "projects"));
            emp.getPhoneNumbers().size();
            assertTrue("PersistenceUnitUtil says phoneNumbers is not loaded when it is", util.isLoaded(emp, "phoneNumbers"));
            assertTrue("PersistenceUnitUtil says firstName is not loaded when it is", util.isLoaded(emp, "firstName"));
        } finally {
            rollbackTransaction(em);
        }
    }

    public void testGetIdentifier(){
        EntityManagerFactory emf = getEntityManagerFactory();
        EntityManager em = createEntityManager();
        beginTransaction(em);
        try{
            Employee emp = new Employee();
            emp.setFirstName("Abe");
            emp.setLastName("Jones");
            Address addr = new Address();
            addr.setCity("Palo Alto");
            emp.setAddress(addr);

            PhoneNumber pn = new PhoneNumber();
            pn.setNumber("1234456");
            pn.setType("Home");
            emp.addPhoneNumber(pn);
            pn.setOwner(emp);
            em.persist(emp);
            em.flush();
            Integer id = emp.getId();

            em.clear();
            clearCache();

            emp = em.find(Employee.class, emp.getId());
            PersistenceUnitUtil util = emf.getPersistenceUnitUtil();
            Object retrievedId = util.getIdentifier(emp);
            assertTrue("Got an incorrect id from persistenceUtil.getIdentifier()", id.equals(retrievedId));
        } finally {
            rollbackTransaction(em);
        }
    }

    public void testIsLoadedWithReference(){
        EntityManager em = createEntityManager();
        beginTransaction(em);
        try{
            Employee emp = new Employee();
            emp.setFirstName("Abe");
            emp.setLastName("Jones");
            Address addr = new Address();
            addr.setCity("Palo Alto");
            emp.setAddress(addr);

            PhoneNumber pn = new PhoneNumber();
            pn.setNumber("1234456");
            pn.setType("Home");
            emp.addPhoneNumber(pn);
            pn.setOwner(emp);

            Employee manager = new Employee();
            manager.addManagedEmployee(emp);
            emp.setManager(manager);


            em.persist(emp);
            em.flush();

            em.clear();
            clearCache();

            emp = em.find(Employee.class, emp.getId());
            emp.getAddress().getCity();
            emp.getPhoneNumbers().size();

            ProviderUtil util = (new PersistenceProvider()).getProviderUtil();
            assertTrue("ProviderUtil did not return LOADED for isLoaded for address when it should.", util.isLoadedWithReference(emp, "address").equals(LoadState.LOADED));
            assertTrue("ProviderUtil did not return LOADED for isLoaded for phoneNumbers when it should.", util.isLoadedWithReference(emp, "phoneNumbers").equals(LoadState.LOADED));
            if (emp instanceof PersistenceWeaved){
                assertTrue("ProviderUtil did not return NOT_LOADED for isLoaded for manager when it should.", util.isLoadedWithReference(emp, "manager").equals(LoadState.NOT_LOADED));
            } else {
                assertTrue("(NonWeaved) ProviderUtil did not return LOADED for isLoaded for manager when it should.", util.isLoadedWithReference(emp, "manager").equals(LoadState.LOADED));
            }
            assertTrue("ProviderUtil did not return NOT_LOADED for isLoaded for projects when it should.", util.isLoadedWithReference(emp, "projects").equals(LoadState.NOT_LOADED));
        } finally {
            rollbackTransaction(em);
        }
    }

    public void testIsLoadedWithoutReference(){
        EntityManager em = createEntityManager();
        beginTransaction(em);
        try{
            Employee emp = new Employee();
            emp.setFirstName("Abe");
            emp.setLastName("Jones");
            Address addr = new Address();
            addr.setCity("Palo Alto");
            emp.setAddress(addr);

            PhoneNumber pn = new PhoneNumber();
            pn.setNumber("1234456");
            pn.setType("Home");
            emp.addPhoneNumber(pn);
            pn.setOwner(emp);

            Employee manager = new Employee();
            manager.addManagedEmployee(emp);
            emp.setManager(manager);

            em.persist(emp);
            em.flush();

            em.clear();
            clearCache();

            ProviderUtil util = (new PersistenceProvider()).getProviderUtil();

            if (emp instanceof PersistenceWeaved){
                assertTrue("ProviderUtil did not return LOADED for isLoaded when it should.", util.isLoaded(emp).equals(LoadState.LOADED));

                emp = em.getReference(Employee.class, emp.getId());
                // If fetch group weaving is off then we will load EAGER mappings and LOADED will be returned.
                if (isWeavingForFetchGroupsEnabled()) {
                    assertTrue("ProviderUtil did not return NOT_LOADED for isLoaded when it should.", util.isLoaded(emp).equals(LoadState.NOT_LOADED));
                } else {
                    assertTrue("ProviderUtil did not return LOADED for isLoaded when it should.", util.isLoaded(emp).equals(LoadState.LOADED));
                }
            } else {
                assertTrue("(NonWeaved) ProviderUtil did not return UNKNOWN for isLoaded when it should.", util.isLoaded(emp).equals(LoadState.UNKNOWN));

                emp = em.getReference(Employee.class, emp.getId());
                assertTrue("(NonWeaved)  ProviderUtil did not return UNKNOWN for isLoaded when it should.", util.isLoaded(emp).equals(LoadState.UNKNOWN));
            }
            assertTrue("ProviderUtil did not return UNKNOWN for isLoaded when it should.", util.isLoaded(new NonEntity()).equals(LoadState.UNKNOWN));

        } finally {
            rollbackTransaction(em);
        }
    }

    public void testIsLoadedWithoutReferenceAttribute(){
        EntityManager em = createEntityManager();
        beginTransaction(em);
        try{
            Employee emp = new Employee();
            emp.setFirstName("Abe");
            emp.setLastName("Jones");
            Address addr = new Address();
            addr.setCity("Palo Alto");
            emp.setAddress(addr);

            PhoneNumber pn = new PhoneNumber();
            pn.setNumber("1234456");
            pn.setType("Home");
            emp.addPhoneNumber(pn);
            pn.setOwner(emp);

            Employee manager = new Employee();
            manager.addManagedEmployee(emp);
            emp.setManager(manager);

            em.persist(emp);
            em.flush();

            em.clear();
            clearCache();

            emp = em.find(Employee.class, emp.getId());
            emp.getAddress().getCity();
            emp.getPhoneNumbers().size();

            ProviderUtil util = (new PersistenceProvider()).getProviderUtil();
            if (emp instanceof PersistenceWeaved){
                assertTrue("ProviderUtil did not return LOADED for isLoaded for address when it should.", util.isLoadedWithReference(emp, "address").equals(LoadState.LOADED));
                assertTrue("ProviderUtil did not return NOT_LOADED for isLoaded for manager when it should.", util.isLoadedWithReference(emp, "manager").equals(LoadState.NOT_LOADED));
            } else {
                assertTrue("(Unweaved) ProviderUtil did not return LOADED for isLoaded for address when it should.", util.isLoadedWithReference(emp, "address").equals(LoadState.LOADED));
                assertTrue("(Unweaved) ProviderUtil did not return LOADED for isLoaded for manager when it should.", util.isLoadedWithReference(emp, "manager").equals(LoadState.LOADED));
            }
            assertTrue("ProviderUtil did not return LOADED for isLoaded for phoneNumbers when it should.", util.isLoadedWithReference(emp, "phoneNumbers").equals(LoadState.LOADED));
            assertTrue("ProviderUtil did not return NOT_LOADED for isLoaded for projects when it should.", util.isLoadedWithReference(emp, "projects").equals(LoadState.NOT_LOADED));

            assertTrue("ProviderUtil did not return UNKNOWN for isLoaded when it should.", util.isLoaded(new NonEntity()).equals(LoadState.UNKNOWN));
        } finally {
            rollbackTransaction(em);
        }
    }

    public void testGetHints(){
        EntityManagerFactory emf = getEntityManagerFactory();
        EntityManager em = emf.createEntityManager();
        Query query = em.createQuery("Select e from Employee e");
        query.setHint(QueryHints.CACHE_USAGE, CacheUsage.DoNotCheckCache);
        query.setHint(QueryHints.BIND_PARAMETERS, "");
        Map<String, Object> hints = query.getHints();
        assertTrue("Incorrect number of hints.", hints.size() == 2);
        assertTrue("CacheUsage hint missing.", hints.get(QueryHints.CACHE_USAGE).equals(CacheUsage.DoNotCheckCache));
        assertTrue("Bind parameters hint missing.", hints.get(QueryHints.BIND_PARAMETERS) != null);

        query = em.createQuery("Select a from Address a");
        hints = query.getHints();
        assertTrue("Hints is not null when it should be.", hints == null);
    }


    public void testTemporalOnClosedEm(){
        if (isOnServer()) {
            // Don't run this test on server.
            return;
        }

        EntityManager em = createEntityManager();
        Query numericParameterQuery = em.createQuery("Select e from Employee e where e.period.startDate = ?1");
        Query namedParameterQuery = em.createQuery("Select e from Employee e where e.period.startDate = :date");
        closeEntityManager(em);
        Exception caughtException = null;
        try{
            numericParameterQuery.setParameter(1, new Date(System.currentTimeMillis()), TemporalType.DATE);
        } catch (Exception e){
            caughtException = e;
        }
        assertTrue("Wrong Exception was caught when setting a numeric temporal Date parameter on a query with a closed em. Caught "+caughtException, caughtException instanceof IllegalStateException);

        try{
            numericParameterQuery.setParameter(1, Calendar.getInstance(), TemporalType.DATE);
        } catch (Exception e){
            caughtException = e;
        }
        assertTrue("Wrong Exception was caught when setting a numeric temporal Calendar parameter on a query with a closed em. Caught "+caughtException, caughtException instanceof IllegalStateException);

        try{
            namedParameterQuery.setParameter("date", new Date(System.currentTimeMillis()), TemporalType.DATE);
        } catch (Exception e){
            caughtException = e;
        }
        assertTrue("Wrong Exception was caught when setting a named temporal Date parameter on a query with a closed em.  Caught "+caughtException, caughtException instanceof IllegalStateException);

        try{
            namedParameterQuery.setParameter("date", Calendar.getInstance(), TemporalType.DATE);
        } catch (Exception e){
            caughtException = e;
        }
        assertTrue("Wrong Exception was caught when setting a named temporal Calendar parameter on a query with a closed em.", caughtException instanceof IllegalStateException);
    }

    public void testTransientMapping(){
        ServerSession session = getServerSession();
        ClassDescriptor descriptor = session.getClassDescriptor(Customer.class);
        assertTrue("There should not be a mapping for transientField.", descriptor.getMappingForAttributeName("transientField") == null);
    }

    public static class SessionNameCustomizer implements SessionCustomizer {
        static ServerSession ss;
        @Override
        public void customize(Session session) throws Exception {
            ss = (ServerSession)session;
        }
    }
    public void testGenerateSessionNameFromConnectionProperties() {
        // the test requires passing properties to createEMF or createContainerEMF method.
        if (isOnServer()) {
            return;
        }

        String errorMsg = "";
        EntityManagerFactory emf;
        Map properties;
        String puName = "default";
        String customizer = "org.eclipse.persistence.testing.tests.jpa.advanced.EntityManagerJUnitTestSuite$SessionNameCustomizer";

        String myJtaDS = "myJtaDS";
        String myNonJtaDS = "myNonJtaDS";
        String myUrl = "myUrl";
        String myUser = "myUser";
        String myDriver = "myDriver";
        String myPassword = "myPassword";

        ServerSession originalSession = JUnitTestCase.getServerSession();
        String loggingLevel = originalSession.getSessionLog().getLevelString();
        SessionNameCustomizer.ss = null;

        // 0: The session name specified in persistence.xml is NOT overridden -> the existing session is used by emf.
        // If persistence.xml no longer specifies session name then comment out this part of the test.
        properties = new HashMap();
        // required by the test
        properties.put(PersistenceUnitProperties.SESSION_CUSTOMIZER, customizer);
        // log on the same level as original session
        properties.put(PersistenceUnitProperties.LOGGING_LEVEL, loggingLevel);
        properties.put(PersistenceUnitProperties.TRANSACTION_TYPE, "RESOURCE_LOCAL");
        // to override data source if one is specified in persistence.xml
        properties.put(PersistenceUnitProperties.JTA_DATASOURCE, "");
        // to override data source if one is specified in persistence.xml
        properties.put(PersistenceUnitProperties.NON_JTA_DATASOURCE, "");
        properties.put(PersistenceUnitProperties.JDBC_URL, myUrl);
        properties.put(PersistenceUnitProperties.JDBC_USER, myUser);
        properties.put(PersistenceUnitProperties.JDBC_DRIVER, myDriver);
        properties.put(PersistenceUnitProperties.JDBC_PASSWORD, myPassword);
        emf = Persistence.createEntityManagerFactory(puName, properties);
        try {
            emf.createEntityManager();
        } catch (Exception ex) {
            // Ignore exception that probably caused by attempt to connect the session with invalid connection data provided in the properties.
        } finally {
            emf.close();
            if(SessionNameCustomizer.ss != null && SessionNameCustomizer.ss != originalSession) {
                errorMsg += "0: Session name NOT overridden by an empty string - original session expected; ";
            }
            // clear for the next test
            SessionNameCustomizer.ss = null;
        }

        // 1: New session with DefaultConnector with myUrl, myDriver, myUser, myPassword
        properties = new HashMap();
        // required by the test
        properties.put(PersistenceUnitProperties.SESSION_CUSTOMIZER, customizer);
        // log on the same level as original session
        properties.put(PersistenceUnitProperties.LOGGING_LEVEL, loggingLevel);
        // to override SESSION_NAME if one is specified in persistence.xml
        properties.put(PersistenceUnitProperties.SESSION_NAME, "");
        properties.put(PersistenceUnitProperties.TRANSACTION_TYPE, "RESOURCE_LOCAL");
        // to override data source if one is specified in persistence.xml
        properties.put(PersistenceUnitProperties.JTA_DATASOURCE, "");
        // to override data source if one is specified in persistence.xml
        properties.put(PersistenceUnitProperties.NON_JTA_DATASOURCE, "");
        properties.put(PersistenceUnitProperties.JDBC_URL, myUrl);
        properties.put(PersistenceUnitProperties.JDBC_USER, myUser);
        properties.put(PersistenceUnitProperties.JDBC_DRIVER, myDriver);
        properties.put(PersistenceUnitProperties.JDBC_PASSWORD, myPassword);
        emf = Persistence.createEntityManagerFactory(puName, properties);
        try {
            emf.createEntityManager();
        } catch (Exception ex) {
            // Ignore exception that probably caused by attempt to connect the session with invalid connection data provided in the properties.
        } finally {
            emf.close();
            if(SessionNameCustomizer.ss == null && SessionNameCustomizer.ss == originalSession) {
                errorMsg += "1: New session expected; ";
            } else {
                if(SessionNameCustomizer.ss.getLogin().shouldUseExternalConnectionPooling()) {
                    errorMsg += "1: internal connection pooling expected; ";
                }
                if(SessionNameCustomizer.ss.getLogin().shouldUseExternalTransactionController()) {
                    errorMsg += "1: no externalTransactionController expected; ";
                }
                if(! myUser.equals(SessionNameCustomizer.ss.getLogin().getUserName())) {
                    errorMsg += "1: myUser expected; ";
                }
                Connector connector = SessionNameCustomizer.ss.getLogin().getConnector();
                if(connector instanceof DefaultConnector) {
                    if(! myUrl.equals(((DefaultConnector)connector).getDatabaseURL())) {
                        errorMsg += "1: myUrl expected; ";
                    }
                    if(! myDriver.equals(((DefaultConnector)connector).getDriverClassName())) {
                        errorMsg += "1: myDriver expected; ";
                    }
                } else {
                    errorMsg += "1: DefaultConnector expected; ";
                }
            }
            // clear for the next test
            SessionNameCustomizer.ss = null;
        }


        // 2: New session with JNDIConnector with myJtaDs, myNonJtaDs
        properties = new HashMap();
        // required by the test
        properties.put(PersistenceUnitProperties.SESSION_CUSTOMIZER, customizer);
        // log on the same level as original session
        properties.put(PersistenceUnitProperties.LOGGING_LEVEL, loggingLevel);
        // to override SESSION_NAME if one is specified in persistence.xml
        properties.put(PersistenceUnitProperties.SESSION_NAME, "");
        properties.put(PersistenceUnitProperties.TRANSACTION_TYPE, "JTA");
        properties.put(PersistenceUnitProperties.JTA_DATASOURCE, myJtaDS);
        properties.put(PersistenceUnitProperties.NON_JTA_DATASOURCE, myNonJtaDS);
        // to override user if one is specified in persistence.xml
        properties.put(PersistenceUnitProperties.JDBC_USER, "");
        // note that there is no need to override JDBC_URL, JDBC_DRIVER, JDBC_PASSWORD with an empty string, they will be ignored.
        // JDBC_URL, JDBC_DRIVER - because data source(s) are specified; JDBC_PASSWORD - because JDBC_USER is not specified
        emf = Persistence.createEntityManagerFactory(puName, properties);
        try {
            emf.createEntityManager();
        } catch (Exception ex) {
            // Ignore exception that probably caused by attempt to connect the session with invalid connection data provided in the properties.
        } finally {
            emf.close();
            if(SessionNameCustomizer.ss == null && SessionNameCustomizer.ss == originalSession) {
                errorMsg += "2: New session expected; ";
            } else {
                if(! SessionNameCustomizer.ss.getLogin().shouldUseExternalConnectionPooling()) {
                    errorMsg += "2: external connection pooling expected; ";
                }
                if(! SessionNameCustomizer.ss.getLogin().shouldUseExternalTransactionController()) {
                    errorMsg += "2: externalTransactionController expected; ";
                }
                if(SessionNameCustomizer.ss.getLogin().getUserName().length() > 0) {
                    errorMsg += "2: empty string user expected; ";
                }
                Connector connector = SessionNameCustomizer.ss.getLogin().getConnector();
                if(connector instanceof JNDIConnector) {
                    if(! myJtaDS.equals(((JNDIConnector)connector).getName())) {
                        errorMsg += "2: myJtaDS expected; ";
                    }
                } else {
                    errorMsg += "2: JNDIConnector expected; ";
                }

                if(! SessionNameCustomizer.ss.getReadConnectionPool().getLogin().shouldUseExternalConnectionPooling()) {
                    errorMsg += "2: resding: external connection pooling expected; ";
                }
                if(SessionNameCustomizer.ss.getReadConnectionPool().getLogin().shouldUseExternalTransactionController()) {
                    errorMsg += "2: reading no externalTransactionController expected; ";
                }
                if(SessionNameCustomizer.ss.getReadConnectionPool().getLogin().getUserName().length() > 0) {
                    errorMsg += "2: reading: empty string user expected; ";
                }
                Connector readConnector = ((DatasourceLogin)SessionNameCustomizer.ss.getReadConnectionPool().getLogin()).getConnector();
                if(readConnector instanceof JNDIConnector) {
                    if(! myNonJtaDS.equals(((JNDIConnector)readConnector).getName())) {
                        errorMsg += "2: reading: myNonJtaDS expected; ";
                    }
                } else {
                    errorMsg += "2: reading: JNDIConnector expected; ";
                }
            }
            // clear for the next test
            SessionNameCustomizer.ss = null;
        }

        if(errorMsg.length() > 0) {
            fail(errorMsg);
        }
    }

    public void testPreupdateEmbeddable(){
        EntityManager em = createEntityManager();
        beginTransaction(em);
        Employee emp = new Employee();
        emp.setFirstName("testPreupdateEmbeddable");
        emp.setLastName("testPreupdateEmbeddable");
        EmploymentPeriod period = new EmploymentPeriod();
        period.setStartDate(Date.valueOf("2002-01-01"));
        emp.setPeriod(period);
        em.persist(emp);
        commitTransaction(em);
        closeEntityManager(em);
        clearCache();

        em = createEntityManager();
        beginTransaction(em);

        emp = em.find(Employee.class, emp.getId());
        emp.setFirstName("testPreupdateEmbeddable1");


        emp = em.merge(emp);

        em.flush();

        clearCache();
        emp = em.find(Employee.class, emp.getId());
        assertTrue("The endDate was not updated.", emp.getPeriod().getEndDate().equals(EmployeeListener.UPDATE_DATE));

        em.remove(emp);
        commitTransaction(em);
    }

    /**
     * Test for Bug 299147 - em.find isolated read-only entity throws exception
     */
    public void testFindReadOnlyIsolated() {
        EntityManager em = createEntityManager();
        beginTransaction(em);
        try {
            // test query
            em.createQuery("SELECT ro FROM ReadOnlyIsolated ro").getResultList();
            // test find - this used to throw exception
            em.find(ReadOnlyIsolated.class, 1);
        } finally {
            if (isTransactionActive(em)){
                rollbackTransaction(em);
            }
            closeEntityManager(em);
        }
    }

    // bug 274975
    public void testInheritanceQuery(){
        EntityManager em = createEntityManager();
        beginTransaction(em);
        LargeProject project = new LargeProject();
        em.persist(project);
        commitTransaction(em);
        int id = project.getId();
        clearCache();

        ClassDescriptor descriptor = getServerSession().getClassDescriptor(Project.class);
        ReadAllQuery query = new ReadAllQuery(Project.class);
        ExpressionBuilder b = query.getExpressionBuilder();
        query.addArgument("id", Integer.class); // declare bind variable in (parent) query

        ReportQuery subQuery = new ReportQuery();
        subQuery.setReferenceClass(Project.class); // use any dummy mapped class...
        SQLCall selectIdsCall = new SQLCall();
        String subSelect = "select p.PROJ_ID from CMP3_PROJECT p where p.PROJ_ID = #id"; // <= re-use bind variable in child query
        selectIdsCall.setSQLString(subSelect);
        subQuery.setCall(selectIdsCall);

        Expression expr = b.get("id").in(subQuery);
        query.setSelectionCriteria(expr);

        // Now execute query with bind variable
        // (using setShouldBindAllParameters(false) makes it work...
        // but this is not good, in particular it prevents use of advanced queries with Oraclearrays as bind-variables!!!)
        Vector params = new Vector(1);
        params.add(id);
        List res = (List) getServerSession().executeQuery(query, params);
        assertTrue(res.size() == 1);
    }

    public void testNullBasicMap(){
        EntityManager em = createEntityManager();
        beginTransaction(em);
        try{
            Buyer buyer = new Buyer();
            buyer.setName("Joe");
            buyer.setDescription("Test Buyer");
            buyer.setCreditCards(null);
            em.persist(buyer);
            em.flush();
            clearCache();
            buyer = em.find(Buyer.class, buyer.getId());
            assertTrue("Buyer was not properly persisted", buyer != null);
        } catch (NullPointerException ex){
            fail("NPE caught when persisting a null Map.");
        } finally {
            rollbackTransaction(em);
        }

    }

    public void testFlushClearFind(){
        Map properties = new HashMap();

        EntityManager em = createEntityManager();
        beginTransaction(em);
        Employee emp = new Employee();
        emp.setFirstName("Cesc");
        emp.setLastName("Fabergass");
        em.persist(emp);
        commitTransaction(em);

        beginTransaction(em);
        emp = em.find(Employee.class, emp.getId());
        emp.setLastName("Fabregas");
        em.flush();
        em.clear();

        emp = em.find(Employee.class, emp.getId());
        commitTransaction(em);
        try{
            assertTrue("Employees name was returned from server cache, when it should not have been", emp.getLastName().equals("Fabregas"));
        } finally {
            beginTransaction(em);
            emp = em.find(Employee.class, emp.getId());
            em.remove(emp);
            commitTransaction(em);
        }
    }

    // Bug 356117
    public void testFlushClearFindNoCascadedLock(){
        Map properties = new HashMap();

        EntityManager em = createEntityManager();
        beginTransaction(em);
        Address add = new Address();
        add.setCity("London");
        em.persist(add);
        commitTransaction(em);

        beginTransaction(em);
        add = em.find(Address.class, add.getID());
        add.setCity("Barcelona");
        em.flush();
        em.clear();

        add = em.find(Address.class, add.getID());
        commitTransaction(em);
        try{
            assertTrue("Address city was returned from server cache, when it should not have been", add.getCity().equals("Barcelona"));
        } finally {
            clearCache();
            em.clear();
            beginTransaction(em);
            add = em.find(Address.class, add.getID());
            em.remove(add);
            commitTransaction(em);
        }
    }

    public void testFlushClearQueryPk(){
        EntityManager em = createEntityManager();
        beginTransaction(em);
        Employee emp = new Employee();
        emp.setFirstName("Cesc");
        emp.setLastName("Fabergass");
        em.persist(emp);
        commitTransaction(em);

        beginTransaction(em);
        emp = em.find(Employee.class, emp.getId());
        emp.setLastName("Fabregas");
        em.flush();
        em.clear();

        emp = (Employee)em.createQuery("select e from Employee e where e.id = :id").setParameter("id", emp.getId()).getSingleResult();
        commitTransaction(em);
        try{
            assertTrue("Employees name was returned from server cache, when it should not have been", emp.getLastName().equals("Fabregas"));
        } finally {
            beginTransaction(em);
            emp = em.find(Employee.class, emp.getId());
            em.remove(emp);
            commitTransaction(em);
        }
    }

    public void testFlushClearQueryNonPK(){
        EntityManager em = createEntityManager();
        beginTransaction(em);
        Employee emp = new Employee();
        emp.setFirstName("Cesc");
        emp.setLastName("Fabergass");
        em.persist(emp);
        commitTransaction(em);

        beginTransaction(em);
        emp = em.find(Employee.class, emp.getId());
        emp.setLastName("Fabregas");
        em.flush();
        em.clear();

        emp = (Employee)em.createQuery("select e from Employee e where e.firstName = :name").setParameter("name", emp.getFirstName()).getSingleResult();
        commitTransaction(em);
        try{
            assertTrue("Employees name was returned from server cache, when it should not have been", emp.getLastName().equals("Fabregas"));
        } finally {
            beginTransaction(em);
            emp = em.find(Employee.class, emp.getId());
            em.remove(emp);
            commitTransaction(em);
        }
    }

    //  Bug 324406 - Wrong Index in ReportItem when @Embeddable Objects are used in ReportQuery
    public void testSelectEmbeddable(){
        EntityManager em = createEntityManager();
        beginTransaction(em);
        Employee emp = new Employee();
        emp.setFirstName("Robin");
        emp.setLastName("Van Persie");
        EmploymentPeriod period = new EmploymentPeriod();
        ;

        period.setStartDate(new Date((new GregorianCalendar(2009, 1, 1)).getTimeInMillis()));
        period.setEndDate(new Date((new GregorianCalendar(2010, 1, 1)).getTimeInMillis()));
        emp.setPeriod(period);
        em.persist(emp);
        em.flush();
        em.clear();
        clearCache();

        EmployeeHolder results = (EmployeeHolder)em.createQuery("select new org.eclipse.persistence.testing.models.jpa.advanced.EmployeeHolder(e.id, e.period, e.firstName) from Employee e where e.id = :id").setParameter("id", emp.getId()).getSingleResult();
        assertTrue("Incorrect id", emp.getId().equals(results.getId()));
        assertTrue("Incorrect period start date", emp.getPeriod().getStartDate().equals(results.getPeriod().getStartDate()));
        assertTrue("Incorrect period end date", emp.getPeriod().getEndDate().equals(results.getPeriod().getEndDate()));
        assertTrue("Incorrect name", emp.getFirstName().equals(results.getName()));

        rollbackTransaction(em);
    }

    // Bug 320254 - Ensure we do not get an exception when using a batch hint that navigates through more than one descriptor
    public void testNestedBatchQueryHint(){
        EntityManager em = createEntityManager();
        beginTransaction(em);
        Department dept = new Department();
        dept.setName("Parents");
        Employee emp = new Employee();
        emp.setFirstName("Dave");
        emp.setLastName("Daddy");
        dept.setDepartmentHead(emp);
        emp.setDepartment(dept);
        PhoneNumber pn = new PhoneNumber();
        pn.setNumber("1234567");
        pn.setAreaCode("613");
        pn.setType("Home");
        emp.addPhoneNumber(pn);
        em.persist(emp);
        em.persist(dept);
        em.persist(pn);
        em.flush();
        em.clear();
        clearCache();

        List results = em.createQuery("select d from ADV_DEPT d").setHint(QueryHints.FETCH, "d.departmentHead").setHint(QueryHints.BATCH, "d.departmentHead.phoneNumbers").getResultList();
        assertTrue("Wrong results returned.", results.size() == 1);

        dept = (Department)results.get(0);
        dept.getDepartmentHead().getPhoneNumbers().hashCode();
        rollbackTransaction(em);
    }

    // Bug 332683 - Problems with ClientSession connections
    // This test verifies that non pooled connection case works.
    public void testNonPooledConnection() {
        ServerSession ss = getServerSession();
        // Normally the user wishing to use not pooled connection would specify user and password properties (and possibly db url, too).
        // However if these properties have the same values that those in the logging then no non pooled connection is created and the pooled one used instead.
        // In the test we must use the same user as already in the session login (don't know any others) that forces usage of ConnectionPolicy property.
        ConnectionPolicy connectionPolicy = (ConnectionPolicy)ss.getDefaultConnectionPolicy().clone();
        connectionPolicy.setLogin(ss.getLogin());
        connectionPolicy.setPoolName(null);
        EntityManager em;
        boolean isEmInjected = isOnServer() && ss.getLogin().shouldUseExternalTransactionController();
        boolean isSpring = isOnServer() && getServerPlatform().isSpring();
        if (isEmInjected) {
            em = createEntityManager();
            // In server jta case need a transaction - otherwise the wrapped EntityManagerImpl is not kept.
            beginTransaction(em);
            em.setProperty(EntityManagerProperties.CONNECTION_POLICY, connectionPolicy);
        } else {
            EntityManagerFactory emFactory = getEntityManagerFactory();
            Map properties = new HashMap(1);
            properties.put(EntityManagerProperties.CONNECTION_POLICY, connectionPolicy);
            em = emFactory.createEntityManager(properties);
            if(isSpring) {
                em.getTransaction().begin();
            } else {
                beginTransaction(em);
            }
        }
        try {
            // native query triggers early begin transaction
            em.createNativeQuery("SELECT F_NAME FROM CMP3_EMPLOYEE").getResultList();
            // verify that the connection is really not pooled.
            assertTrue("Test problem: connection should be not pooled", em.unwrap(UnitOfWork.class).getParent().getAccessor().getPool() == null);
        } finally {
            if(isSpring) {
                em.getTransaction().rollback();
            } else {
                rollbackTransaction(em);
            }
            closeEntityManager(em);
        }
    }

    //  Bug 332464 - EntityManager running out of connections in exclusive isolated client session mode
    public void testExclusiveIsolatedLeaksConnectionOnClear() {
        ServerSession ss = getServerSession();
        EntityManager em;
        boolean isEmInjected = isOnServer() && ss.getLogin().shouldUseExternalTransactionController();
        boolean isSpring = isOnServer() && getServerPlatform().isSpring();
        if (isEmInjected) {
            em = createEntityManager();
            // In server jta case need a transaction - otherwise the wrapped EntityManagerImpl is not kept.
            beginTransaction(em);
            em.setProperty(EntityManagerProperties.EXCLUSIVE_CONNECTION_MODE, "Always");
        } else {
            EntityManagerFactory emFactory = getEntityManagerFactory();
            Map properties = new HashMap(1);
            properties.put(EntityManagerProperties.EXCLUSIVE_CONNECTION_MODE, "Always");
            em = emFactory.createEntityManager(properties);
            if(isSpring) {
                em.getTransaction().begin();
            } else {
                beginTransaction(em);
            }
        }

        // any query on ExclusiveIsolated session triggers the exclusive connection to be acquired.
        em.createQuery("SELECT e FROM Employee e").getResultList();
        // the exclusive connection
        Accessor accessor = em.unwrap(UnitOfWork.class).getParent().getAccessor();
        // connection is still held because it's an ExclusiveIsolatedSession
        if(isSpring) {
            em.getTransaction().commit();
        } else {
            commitTransaction(em);
        }
        // before the bug was fixed that used to simply nullify the uow without releasing it and its parent ExclusiveIsolatedSession.
        em.clear();
        // closing EntityManager should release the exclusive connection.
        closeEntityManager(em);

        // verify that the connection has been released
        boolean released;
        ConnectionPool pool = ss.getDefaultConnectionPool();
        if(ss.getLogin().shouldUseExternalConnectionPooling()) {
            // external pool case
            released = accessor.getConnection() == null;
        } else {
            // intrenal pool case
            released = pool.getConnectionsAvailable().contains(accessor);
        }

        if(!released) {
            // release connection
            pool.releaseConnection(accessor);
            fail("Exclusive connection has not been released after the EntityManager has been closed.");
        }
    }

    // Bug 331692
    public void testSetTargetQueryOneToMany(){
        if (isOnServer()) {
            return;
        }

        EntityManager em = createEntityManager("customizeAddTarget");
        beginTransaction(em);
        Employee emp = new Employee();
        emp.setFirstName("Nick");
        em.persist(emp);
        em.flush();
        emp.addDealer(new Dealer());
        em.flush();
        em.clear();
        clearCache("customizeAddTarget");

        emp = em.find(Employee.class, emp.getId());
        rollbackTransaction(em);

        assertTrue("The add Target Query was not correctly customized", emp.getFirstName() == null);
    }

        public void testSettingDetachedObject() {
            EntityManager em = createEntityManager();
                List<Address> results = em.createQuery("Select a from Address a").getResultList();
                Department dept1 = new Department("Dept1");
                Department dept2 = new Department("Dept2");
                beginTransaction(em);
                em.persist(dept1);
                em.persist(dept2);
                commitTransaction(em);
                em.clear();

                Employee emp = new Employee("Bob", "Bob");
                beginTransaction(em);
                em.persist(emp);
                emp.setDepartment(dept1);
                em.flush();
                emp.setDepartment(dept2); //<-- only the UOW is checked for existence
                commitTransaction(em); //<-- fails here
            }


    public void testMergeOfEntityWithDetachedReferences() {
        EntityManager em = null;
        Dealer dealer = new Dealer();

        try {
            em = createEntityManager();
            beginTransaction(em);
            em.persist(dealer);
            commitTransaction(em);
            em.clear();
            em = createEntityManager();
            beginTransaction(em);
            dealer = em.find(Dealer.class, dealer.getId());

            Customer customer = new Customer();
            customer.setFirstName("p2");
            dealer.addCustomer(customer);

            customer = new Customer();
            customer.setFirstName("p3");
            dealer.addCustomer(customer);

            dealer = em.merge(dealer);
            commitTransaction(em);
            beginTransaction(em);
            dealer = em.find(Dealer.class, dealer.getId());
            dealer.getCustomers().get(1).setFirstName("SOMENUMBER");
            commitTransaction(em);
        } catch (Exception e) {
            if (isTransactionActive(em)) {
                rollbackTransaction(em);
            }
            fail("En error occurred adding new customers: " + e.getMessage());
        } finally {
            if (em != null) {
                closeEntityManager(em);
            }
        }

        try {
            em = createEntityManager();
            beginTransaction(em);
            dealer = em.find(Dealer.class, dealer.getId());
            boolean changedName = false;
            for (Customer customer : dealer.getCustomers()) {
                if (customer == null) {
                    fail("A null Customer was found in the collection of Customers.");
                }
                if (customer.getFirstName() == null || customer.getFirstName().equals("")) {
                    fail("Attributes not merged into collection");
                }
                if (dealer.getCustomers().lastIndexOf(customer) != dealer.getCustomers().indexOf(customer)) {
                    fail("Customer instance referenced multiple times ");
                }
                if (customer.getFirstName().equals("SOMENUMBER")){
                    changedName = true;
                }
            }
            assertTrue("Merge identiy lost ", changedName);

        } catch (Exception e) {
            if (isTransactionActive(em)) {
                rollbackTransaction(em);
            }

            fail("En error occurred fetching the results to verify: " + e.getMessage());
        } finally {
            commitTransaction(em);
            if (em != null) {
                closeEntityManager(em);
            }
            try {
                em = createEntityManager();
                beginTransaction(em);
                dealer = em.find(Dealer.class, dealer.getId());
                em.remove(dealer);
                for (Customer customer : dealer.getCustomers()) {
                    em.remove(customer);
                }
                dealer.getCustomers().clear();
                commitTransaction(em);
            } finally {
                if (em != null) {
                    closeEntityManager(em);
                }
            }
        }
    }

    // Bug 335322
    public void testRefreshForFlush(){
        EntityManager em = createEntityManager();
        beginTransaction(em);
        Employee emp = new Employee();
        emp.setFirstName("Al");
        em.persist(emp);
        em.flush();
        em.clear();

        clearCache();
        emp = em.find(Employee.class, emp.getId());
        emp.setFirstName("Joe");
        em.refresh(emp);
        emp.setLastName("Joseph");
        em.flush();

        em.refresh(emp);
        try {
            assertFalse("The first name was updated even though it was reverted.", emp.getFirstName().equals("Joe"));
        } finally {
            rollbackTransaction(em);
        }
    }

    public void testRefreshLazyRelationship(){
        if (isOnServer()){
            return;
        }
        EntityManager setupEm = createEntityManager();
        setupEm.getTransaction().begin();
        Employee emp = new Employee();
        setupEm.persist(emp);
        Employee direct = new Employee("Managed", "EMployee");
        setupEm.persist(direct);
        emp.getManagedEmployees().add(direct);
        direct.setManager(emp);
        setupEm.getTransaction().commit();
        clearCache();

        EntityManager em1 = createEntityManager();
        EntityManager em2 = createEntityManager();

        emp = em1.find(Employee.class, emp.getId());
        Employee emp2 = em2.find(Employee.class, emp.getId());
        Employee direct2 = em2.find(Employee.class, direct.getId());

        em1.getTransaction().begin();
        emp.getManagedEmployees().iterator().next().setFirstName("something");
        em1.getTransaction().commit();

        em2.refresh(emp2);
        try{
            assertEquals("Did not cascade refresh across untriggered lazy", emp2.getManagedEmployees().iterator().next().getFirstName(), "something");
        }finally{
            try{
                em2.getTransaction().begin();
                em2.remove(emp2);
                em2.remove(direct2);
                em2.getTransaction().commit();
            }catch (Exception e){

            }
        }

    }

    // Bug 335322
    public void testNonRefreshLazyRelationship(){
        if (isOnServer()){
            return;
        }

        EntityManager setupEm = createEntityManager();
        setupEm.getTransaction().begin();
        Employee emp = new Employee();
        setupEm.persist(emp);
        Employee direct = new Employee("Managed", "EMployee");
        setupEm.persist(direct);
        emp.getManagedEmployees().add(direct);
        direct.setManager(emp);
        Dealer dealer = new Dealer("Jim", "Bob");
        emp.getDealers().add(dealer);
        setupEm.persist(dealer);
        Project project = new LargeProject("Alpha Alpha Zulu");
        setupEm.persist(project);
        emp.getProjects().add(project);
        setupEm.getTransaction().commit();
        clearCache();

        EntityManager em1 = createEntityManager();
        EntityManager em2 = createEntityManager();

        emp = em1.find(Employee.class, emp.getId());
        Employee emp2 = em2.find(Employee.class, emp.getId());
        Employee direct2 = em2.find(Employee.class, direct.getId());
        Dealer dealer2 = em2.find(Dealer.class, dealer.getId());
        Project project2 = em2.find(Project.class, project.getId());

        em1.getTransaction().begin();
        emp.getManagedEmployees().iterator().next().setFirstName("something");
        emp.getDealers().get(0).setFirstName("Something");
        emp.getProjects().iterator().next().setName("Beta Beta Wiskey");
        em1.getTransaction().commit();

        em2.refresh(emp2);
        try{
            assertEquals("Did not cascade refresh across untriggered lazy", emp2.getManagedEmployees().iterator().next().getFirstName(), "something");
            assertEquals("Cascaded refresh to non cascade refresh entity", emp2.getDealers().get(0).getFirstName(), "Jim");
            assertEquals("Cascade refresh to non cascade refresh", emp2.getProjects().iterator().next().getName(), "Alpha Alpha Zulu");
        }finally{
            try{
                em2.getTransaction().begin();
                em2.remove(emp2);
                em2.remove(direct2);
                em2.remove(dealer2);
                em2.remove(project2);
                em2.getTransaction().commit();
            }catch (Exception e){

            }
        }

    }

    public void testRefreshForCommit(){
        EntityManager em = createEntityManager();
        beginTransaction(em);
        Employee emp = new Employee();
        emp.setFirstName("Al");
        em.persist(emp);
        commitTransaction(em);
        em.clear();

        clearCache();
        beginTransaction(em);
        emp = em.find(Employee.class, emp.getId());
        emp.setFirstName("Joe");
        em.refresh(emp);
        emp.setLastName("Joseph");
        commitTransaction(em);

        beginTransaction(em);
        try{
            emp = em.find(Employee.class, emp.getId());
            em.refresh(emp);
            assertFalse("The first name was updated even though it was reverted.", emp.getFirstName().equals("Joe"));
        } finally {
            em.remove(emp);
            commitTransaction(em);
        }
    }

    // Bug 335322
    public void testChangeFlushChangeRefresh(){
        EntityManager em = createEntityManager();
        beginTransaction(em);
        Employee emp = new Employee();
        emp.setFirstName("Al");
        em.persist(emp);
        commitTransaction(em);
        em.clear();
        clearCache();

        beginTransaction(em);
        emp = em.find(Employee.class, emp.getId());
        emp.setFirstName("Joe");
        em.flush();

        emp.setLastName("Joseph");
        em.refresh(emp);
        commitTransaction(em);

        em.clear();
        clearCache();

        beginTransaction(em);
        try{
            emp = em.find(Employee.class, emp.getId());
            assertTrue("The first name was reverted even though it was written.", emp.getFirstName().equals("Joe"));
        } finally {
            em.remove(emp);
            commitTransaction(em);
        }
    }

    //  Bug 307433 - Regression in Auditing Support when using defaults.
    public static class ChangeRecordKeepOldValueListener extends SessionEventAdapter {
        public UnitOfWorkChangeSet uowChangeSet;
        @Override
        public void postCalculateUnitOfWorkChangeSet(SessionEvent event) {
            uowChangeSet = (UnitOfWorkChangeSet)event.getProperty("UnitOfWorkChangeSet");
        }
    }
    public void testChangeRecordKeepOldValue_Simple() {
        internalTestChangeRecordKeepOldValue(false);
    }
    public void testChangeRecordKeepOldValue_TwoStep() {
        internalTestChangeRecordKeepOldValue(true);
    }
    public void internalTestChangeRecordKeepOldValue(boolean addSecondStep) {
        if(isOnServer()) {
            // the test relies upon keeping attached objects between transactions.
            return;
        }

        ServerSession ss = getServerSession();
        ChangeRecordKeepOldValueListener listener = new ChangeRecordKeepOldValueListener();
        ss.getEventManager().addListener(listener);

        EntityManager em = createEntityManager();
        try {
            // setup
            // create original object and referenced objects
            Employee emp = new Employee();
            emp.setFirstName("TestChangeRecordKeepOldValue");
            emp.setLastName("Manager_OriginalName");
            emp.setMale();
            emp.setSalary(35000);
            emp.setPeriod(new EmploymentPeriod(Helper.dateFromYearMonthDate(1993, 0, 1), Helper.dateFromYearMonthDate(1996, 11, 31)));
            emp.setFormerEmployment(new FormerEmployment("Original", new EmploymentPeriod(Helper.dateFromYearMonthDate(1990, 0, 1), Helper.dateFromYearMonthDate(1993, 11, 31))));
            Address address = new Address();
            address.setCountry("Original");
            address.setProvince("Original");
            address.setCity("Original");
            address.setStreet("Original");
            address.setPostalCode("Original");
            emp.setAddress(address);
            Department dep = new Department();
            dep.setName("Original");
            emp.setDepartment(dep);
            emp.addResponsibility("Original_1");
            emp.addResponsibility("Original_2");
            PhoneNumber phone1 = new PhoneNumber("Original_1", "111", "1111111");
            emp.addPhoneNumber(phone1);
            PhoneNumber phone2 = new PhoneNumber("Original_2", "222", "2222222");
            emp.addPhoneNumber(phone2);
            emp.setNormalHours(new Time[]{Helper.timeFromHourMinuteSecond(9, 0, 0), Helper.timeFromHourMinuteSecond(17, 0, 0)});
            Employee emp1 = new Employee();
            emp1.setFirstName("TestChangeRecordKeepOldValue");
            emp1.setLastName("Original_1");
            emp.addManagedEmployee(emp1);
            Employee emp2 = new Employee();
            emp2.setFirstName("TestChangeRecordKeepOldValue");
            emp2.setLastName("Original_2");
            emp.addManagedEmployee(emp2);
            Project proj1 = new SmallProject();
            proj1.setName("Original_1");
            emp.addProject(proj1);
            Project proj2 = new LargeProject();
            proj2.setName("Original_2");
            emp.addProject(proj2);
            Project proj3 = new LargeProject();
            proj3.setName("Original_3");
            proj3.setTeamLeader(emp);
            emp1.addProject(proj3);
            emp2.addProject(proj3);

            // persist original object and all referenced objects
            beginTransaction(em);
            Equipment equipment1 = new Equipment();
            equipment1.setDescription("Original_1");
            // persist is not cascaded for department.equipment - have to explicitly persist it.
            em.persist(equipment1);
            dep.addEquipment(equipment1);
            Equipment equipment2 = new Equipment();
            equipment2.setDescription("Original_2");
            // persist is not cascaded for department.equipment - have to explicitly persist it.
            // moreover, equipment.id is used as a key in dep.equipment Map, therefore equipmet
            // should be persisted before been added to dep.
            em.persist(equipment2);
            dep.addEquipment(equipment2);
            // persist is not cascaded for employee.department - have to explicitly persist it.
            // moreover, equipment.id is used as a key in dep.equipment Map, therefore equipmet
            // should be persisted before been added to dep.
            em.persist(dep);
            em.persist(emp);
            commitTransaction(em);

            // backup original object and all referenced objects
            CopyGroup copyGroupBackup = new CopyGroup();
            copyGroupBackup.cascadeAllParts();
            ss.copy(emp, copyGroupBackup);
            // emp references (directly or through other objects) all the created objects, therefore all of them are copied.
            Map backupMap = copyGroupBackup.getCopies();

            // verify that backup objects are identical to originals
            Iterator<Map.Entry> it = backupMap.entrySet().iterator();
            while(it.hasNext()) {
                Map.Entry entry = it.next();
                Object original = entry.getKey();
                ClassDescriptor descriptor = ss.getDescriptor(original);
                if(!descriptor.isAggregateDescriptor()) {
                    Object backup = entry.getValue();
                    if(original == backup) {
                        fail("Test problem: backup failed: original == backup: " + original);
                    }
                    if(!ss.compareObjects(original, backup)) {
                        fail("Test problem: backup failed: compareObjects(original, backup) == false: " + original + "; " + backup);
                    }
                }
            }

            // change original object
            beginTransaction(em);
            // DirectToField
            emp.setLastName("Manager_NewName");
            // DirectToField
            emp.setSalary(100);
            // Aggregate
            emp.getPeriod().setStartDate(Helper.dateFromYearMonthDate(2000, 0, 1));
            emp.getPeriod().setEndDate(Helper.dateFromYearMonthDate(2002, 0, 1));
            // Aggregate
//            emp.setFormerEmployment(new FormerEmployment("New", new EmploymentPeriod(Helper.dateFromYearMonthDate(1989, 0, 1), Helper.dateFromYearMonthDate(1992, 11, 31))));
            emp.getFormerEmployment().setFormerCompany("New");
            emp.getFormerEmployment().getPeriod().setStartDate(Helper.dateFromYearMonthDate(1989, 0, 1));
            emp.getFormerEmployment().getPeriod().setStartDate(Helper.dateFromYearMonthDate(1992, 11, 31));
            // Transformation
            emp.setStartTime(Helper.timeFromHourMinuteSecond(10, 0, 0));
            // DirectCollection
            emp.removeResponsibility("Original_1");
            emp.addResponsibility("New_1");
            // Private Collection 1 to many
            PhoneNumber phone1New = new PhoneNumber("New_1", "111", "1111111");
            emp.addPhoneNumber(phone1New);
            emp.removePhoneNumber(phone1);
            // Collection 1 to many
            emp.removeManagedEmployee(emp1);
            emp1.setManager(null);
            em.remove(emp1);
            Employee emp1New = new Employee();
            emp1New.setFirstName("TestChangeRecordKeepOldValue");
            emp1New.setLastName("New_1");
            emp1New.addProject(proj3);
            emp.addManagedEmployee(emp1New);
            // Collection many to many
            emp.removeProject(proj1);
            em.remove(proj1);
            Project proj1New = new LargeProject();
            proj1New.setName("New_1");
            emp.addProject(proj1New);
            // ObjectReference
            proj3.setTeamLeader(null);
            // ObjectReference
            Address addressNew = new Address();
            addressNew.setCountry("New");
            addressNew.setProvince("New");
            addressNew.setCity("New");
            addressNew.setStreet("New");
            addressNew.setPostalCode("New");
            emp.setAddress(addressNew);
            em.remove(address);
            // Map 1 to many
            dep.getEquipment().remove(equipment1.getId());
            Equipment equipment1New = new Equipment();
            equipment1New.setDescription("New_1");
            em.persist(equipment1New);
            dep.addEquipment(equipment1New);

            // additional change typically overrides existing aggregate or collection with the new one, then alters aggregate or adds to collection.
            if(addSecondStep) {
                // Aggregate
                emp.setPeriod(new EmploymentPeriod());
                emp.getPeriod().setStartDate(Helper.dateFromYearMonthDate(2001, 0, 1));
                emp.getPeriod().setEndDate(Helper.dateFromYearMonthDate(2003, 0, 1));
                // Aggregate
                emp.setFormerEmployment(new FormerEmployment("New_New", new EmploymentPeriod(Helper.dateFromYearMonthDate(1988, 0, 1), Helper.dateFromYearMonthDate(1991, 11, 31))));
                emp.getFormerEmployment().setPeriod(new EmploymentPeriod());
                emp.getFormerEmployment().getPeriod().setStartDate(Helper.dateFromYearMonthDate(1987, 0, 1));
                emp.getFormerEmployment().getPeriod().setEndDate(Helper.dateFromYearMonthDate(1990, 0, 1));
                // Transformation
                emp.setEndTime(Helper.timeFromHourMinuteSecond(18, 0, 0));
                // DirectCollection
                emp.setResponsibilities(new ArrayList());
                emp.addResponsibility("New_New_1");
                // Private Collection 1 to many
                emp.setPhoneNumbers(new HashSet());
                PhoneNumber phone1NewNew = new PhoneNumber("New_New_1", "111", "1111111");
                emp.addPhoneNumber(phone1NewNew);
                // Collection 1 to many
                emp1New.setManager(null);
                emp2.setManager(null);
                emp.setManagedEmployees(new Vector());
                Employee emp1NewNew = new Employee();
                emp1NewNew.setFirstName("TestChangeRecordKeepOldValue");
                emp1NewNew.setLastName("New_New_1");
                emp1NewNew.addProject(proj3);
                emp.addManagedEmployee(emp1NewNew);
                em.remove(emp1New);
                em.remove(emp2);
                // Collection many to many
                emp.setProjects(new ArrayList());
                Project proj1NewNew = new LargeProject();
                proj1NewNew.setName("New_New_1");
                emp.addProject(proj1NewNew);
                em.remove(proj1New);
                em.remove(proj2);
                // ObjectReference
                Address addressNewNew = new Address();
                addressNewNew.setCountry("New_New");
                addressNewNew.setProvince("New_New");
                addressNewNew.setCity("New_New");
                addressNewNew.setStreet("New_New");
                addressNewNew.setPostalCode("New_New");
                emp.setAddress(addressNewNew);
                em.remove(addressNew);
                // Map 1 to many
                // We are about to override equipment map.
                // It's a private OneToMany mapping so normally all the
                // members would be removed automatically.
                // However in theis case we have explicitly persisted the the new member added in thhe current transaction
                // (because Equipment's id is used as its key in the Department.equipment Map)
                // therefore we have to explicitly em.remove it.
                em.remove(equipment1New);
                dep.setEquipment(new HashMap());
                Equipment equipment1NewNew = new Equipment();
                equipment1NewNew.setDescription("New_New_1");
                em.persist(equipment1NewNew);
                dep.addEquipment(equipment1NewNew);
            }
            commitTransaction(em);

            // backup updated objects
            CopyGroup copyGroupUpdated = new CopyGroup();
            copyGroupUpdated.cascadeAllParts();
            ss.copy(emp, copyGroupUpdated);
            // copies of the updated objects will be altered to contain old values.
            // if altering the test, make sure that emp still references (directly or through other objects) all the updated objects, so that all of them are copied.
            Map oldValueMap = copyGroupUpdated.getCopies();
            // using ChangeRecords bring back the original state of the object
            Iterator itChangeSets = ((org.eclipse.persistence.internal.sessions.UnitOfWorkChangeSet)listener.uowChangeSet).getCloneToObjectChangeSet().entrySet().iterator();
            while(itChangeSets.hasNext()) {
                Map.Entry entry = (Map.Entry)itChangeSets.next();
                Object object = entry.getKey();
                ClassDescriptor descriptor = ss.getDescriptor(object);
                if(!descriptor.isAggregateDescriptor()) {
                    ObjectChangeSet changeSet = (ObjectChangeSet)entry.getValue();
                    if(!((org.eclipse.persistence.internal.sessions.ObjectChangeSet)changeSet).shouldBeDeleted() && !changeSet.isNew()) {
                        List<ChangeRecord> changes = changeSet.getChanges();
                        if(changes != null && !changes.isEmpty()) {
                            Object oldValueObject = oldValueMap.get(object);
                            for(ChangeRecord changeRecord : changeSet.getChanges()) {
                                Object oldValue = changeRecord.getOldValue();
                                DatabaseMapping mapping = ((org.eclipse.persistence.internal.sessions.ChangeRecord)changeRecord).getMapping();
                                mapping.setRealAttributeValueInObject(oldValueObject, oldValue);
                            }
                        }
                    }
                }
            }

            String errorMsgOldValues = "";
            // now compare oldValue objects with corresponding backup objects
            itChangeSets = ((org.eclipse.persistence.internal.sessions.UnitOfWorkChangeSet)listener.uowChangeSet).getCloneToObjectChangeSet().entrySet().iterator();
            while(itChangeSets.hasNext()) {
                Map.Entry entry = (Map.Entry)itChangeSets.next();
                Object object = entry.getKey();
                ClassDescriptor descriptor = ss.getDescriptor(object);
                if(!descriptor.isAggregateDescriptor()) {
                    ObjectChangeSet changeSet = (ObjectChangeSet)entry.getValue();
                    if(!((org.eclipse.persistence.internal.sessions.ObjectChangeSet)changeSet).shouldBeDeleted() && !changeSet.isNew()) {
                        List<ChangeRecord> changes = changeSet.getChanges();
                        if(changes != null && !changes.isEmpty()) {
                            Object oldValueObject = oldValueMap.get(object);
                            Object backupObject = backupMap.get(object);
                            // compare oldValue with backup object
                            if(!ss.compareObjects(oldValueObject, backupObject)) {
                                errorMsgOldValues += '\t' + object.toString() + '\n';
                            }
                        }
                    }
                }
            }

            // set of attached to em objects
            Set updatedObjects = new HashSet();
            for(Object object : oldValueMap.keySet()) {
                ClassDescriptor descriptor = ss.getDescriptor(object);
                if(!descriptor.isAggregateDescriptor()) {
                    updatedObjects.add(object);
                }
            }

            // verify that the objects were correctly written to the db
            String errorMsgDb = "";
            clearCache();
            Map updatedToReadBack = new HashMap();
            EntityManager em2 = createEntityManager();
            beginTransaction(em2);
            UnitOfWork uow2 = ((EntityManagerImpl)em2.getDelegate()).getActivePersistenceContext(null);
            // read back from the db all the attached to em objects.
            // before comparison clear all read-only mappings that we didn't set in the attached to em objects.
            for(Object object : updatedObjects) {
                Object readBack = uow2.readObject(object);
                if(readBack instanceof Project) {
                    ((Project)readBack).getTeamMembers().clear();
                } else if(readBack instanceof Address) {
                    ((Address)readBack).getEmployees().clear();
                } else if(readBack instanceof PhoneNumber) {
                    ((PhoneNumber)readBack).setId(null);
                } else if(readBack instanceof Department) {
                    ((Department)readBack).getEmployees().clear();
                }
                updatedToReadBack.put(object, readBack);
            }
            // now compare object attached to em with the object read from the db
            for(Object entryObject : updatedToReadBack.entrySet()) {
                Map.Entry entry = (Map.Entry)entryObject;
                Object object = entry.getKey();
                Object readBack = entry.getValue();
                if(!ss.compareObjects(object, readBack)) {
                    errorMsgDb += '\t' + object.toString() + '\n';
                }
            }
            rollbackTransaction(em2);

            // clean up
            beginTransaction(em);
            Set objectsToRemove = new HashSet();
            // remove all dependencies and add cache objects to be directly removed.
            for(Object object : updatedObjects) {
                if(object instanceof Employee) {
                    ((Employee)object).getManagedEmployees().clear();
                    ((Employee)object).setManager(null);
                    ((Employee)object).setAddress((Address)null);
                    ((Employee)object).getProjects().clear();
                    ((Employee)object).setDepartment(null);
                    objectsToRemove.add(object);
                } else if(object instanceof Project) {
                    ((Project)object).setTeamLeader(null);
                    objectsToRemove.add(object);
                } else if(object instanceof Address || object instanceof Department) {
                    objectsToRemove.add(object);
                }
            }
            // remove objects that should be removed directly.
            for(Object object : objectsToRemove) {
                em.remove(object);
            }
            commitTransaction(em);

            String errorMsg = "";
            if(errorMsgOldValues.length() > 0) {
                errorMsgOldValues = "Some old values and back up objects are not equal:\n" + errorMsgOldValues;
                errorMsg += errorMsgOldValues;
            }
            if(errorMsgDb.length() > 0) {
                errorMsgDb = "\nSome values were incorrectly written into the db:\n" + errorMsgDb;
                errorMsg += errorMsgDb;
            }
            if(errorMsg.length() > 0) {
                fail(errorMsg);
            }
        } finally {
            if(isTransactionActive(em)) {
                rollbackTransaction(em);
            }
            closeEntityManager(em);
            ss.getEventManager().removeListener(listener);
        }
    }

    //  Bug 307433 - Regression in Auditing Support when using defaults.
    public void testSetNewAggregate() {
        // setup
        EntityManager em = createEntityManager();
        Employee emp = new Employee();
        emp.setPeriod(new EmploymentPeriod(Helper.dateFromYearMonthDate(1988, 0, 1), Helper.dateFromYearMonthDate(1991, 11, 31)));
        beginTransaction(em);
        em.persist(emp);
        commitTransaction(em);
        int id = emp.getId();

        // test
        beginTransaction(em);
        if(isOnServer() && isJTA()) {
            emp = em.find(Employee.class, id);
        }
        emp.getPeriod().setStartDate(Helper.dateFromYearMonthDate(1989, 0, 1));
        emp.getPeriod().setEndDate(Helper.dateFromYearMonthDate(1992, 0, 1));
        emp.setPeriod(new EmploymentPeriod(Helper.dateFromYearMonthDate(1989, 0, 1), Helper.dateFromYearMonthDate(1992, 11, 31)));
        commitTransaction(em);
        closeEntityManager(em);

        // verify
        clearCache();
        em = createEntityManager();
        beginTransaction(em);
        Employee empRead = em.find(Employee.class, id);
        //clean-up
        em.remove(empRead);
        commitTransaction(em);
        closeEntityManager(em);

        assertTrue("Wrong emp.getPeriod() inserted into db", emp.getPeriod().equals(empRead.getPeriod()));
    }

    //  Bug 307433 - Regression in Auditing Support when using defaults.
    public void testSetNewNestedAggregate() {
        // setup
        EntityManager em = createEntityManager();
        Employee emp = new Employee();
        emp.setFormerEmployment(new FormerEmployment("A", new EmploymentPeriod(Helper.dateFromYearMonthDate(1988, 0, 1), Helper.dateFromYearMonthDate(1991, 11, 31))));
        beginTransaction(em);
        em.persist(emp);
        commitTransaction(em);
        int id = emp.getId();

        // test
        beginTransaction(em);
        if(isOnServer() && isJTA()) {
            emp = em.find(Employee.class, id);
        }
        emp.setFormerEmployment(new FormerEmployment("B", new EmploymentPeriod(Helper.dateFromYearMonthDate(1987, 0, 1), Helper.dateFromYearMonthDate(1990, 11, 31))));
        commitTransaction(em);
        closeEntityManager(em);

        // verify
        clearCache();
        em = createEntityManager();
        beginTransaction(em);
        Employee empRead = em.find(Employee.class, id);
        //clean-up
        em.remove(empRead);
        commitTransaction(em);
        closeEntityManager(em);

        assertTrue("Wrong emp.getFormerEmployment().getPeriod() inserted into db", emp.getFormerEmployment().getPeriod().equals(empRead.getFormerEmployment().getPeriod()));
    }

    //  Bug 307433 - Regression in Auditing Support when using defaults.
    public void testSetStartTime() {
        // setup
        EntityManager em = createEntityManager();
        Employee emp = new Employee();
        emp.setNormalHours(new Time[]{Helper.timeFromHourMinuteSecond(0, 0, 0), Helper.timeFromHourMinuteSecond(8, 0, 0)});
        beginTransaction(em);
        em.persist(emp);
        commitTransaction(em);
        int id = emp.getId();

        // test
        beginTransaction(em);
        if(isOnServer() && isJTA()) {
            emp = em.find(Employee.class, id);
        }
        emp.setStartTime(Helper.timeFromHourMinuteSecond(15, 0, 0));
        commitTransaction(em);
        closeEntityManager(em);

        // verify
        clearCache();
        em = createEntityManager();
        beginTransaction(em);
        Employee empRead = em.find(Employee.class, id);
        //clean-up
        em.remove(empRead);
        commitTransaction(em);
        closeEntityManager(em);

        assertTrue("inserted startTime: " + emp.getStartTime() + " != read back startTime: " + empRead.getStartTime(), emp.getStartTime().equals(empRead.getStartTime()));
    }

    //  Bug 336280 - Same object referenced from both EM cache and shared cache
    public void testObjectReferencedInBothEmAndSharedCache_ObjectReferenceMappingVH() {
        EntityManager em = createEntityManager();

        Employee emp = new Employee();
        emp.setFirstName("Manager");

        Employee emp1 = new Employee();
        emp1.setFirstName("1");
        emp.addManagedEmployee(emp1);
        Employee emp2 = new Employee();
        emp2.setFirstName("2");
        emp.addManagedEmployee(emp2);

        ServerSession ss = null;
        beginTransaction(em);
        em.persist(emp);
        // in JTA case transaction required to obtain ServerSession through getServersession method.
        ss = getServerSession();
        commitTransaction(em);

        CopyGroup copyGroup = new CopyGroup();
        copyGroup.cascadeAllParts();
        ss.copy(emp, copyGroup);

        Set originalObjects = copyGroup.getCopies().keySet();
        // copyGroup cascades through all mappings.
        // originalObjects should consist of just three objects: emp, emp1, emp2.
        // However if manager_vh is wrapped around manager instance from the shared cache (empShared),
        // the size will be 6: emp, emp1, emp2 and empShared, emp1Shared, emp2Shared.
        assertTrue(originalObjects.size() == 3);
    }

    //  Bug 336280 - Same object referenced from both EM cache and shared cache
    public void testObjectReferencedInBothEmAndSharedCache_AggregateObjectMapping() {
        EntityManager em = createEntityManager();

        ServerSession ss = null;
        // persist a new Employee object
        Employee emp = new Employee();
        emp.setFirstName("A");
        EmploymentPeriod period = new EmploymentPeriod(Helper.dateFromYearMonthDate(1993, 0, 1), Helper.dateFromYearMonthDate(1996, 11, 31));
        emp.setPeriod(period);
        beginTransaction(em);
        em.persist(emp);
        // in JTA case transaction required to obtain ServerSession through getServersession method.
        ss = getServerSession();
        commitTransaction(em);
        closeEntityManager(em);

        // using query by example read empShared corresponding to emp in ghe share cache
        Employee empShared = (Employee)ss.readObject(emp);
        // these are really to distinct objects
        assertTrue(emp != empShared);
        // they should not share the aggragate
        assertTrue(emp.getPeriod() != empShared.getPeriod());
    }

    public void testCharFieldDefaultNullValue() {
        EntityManager em = createEntityManager();
        beginTransaction(em);

        Vegetable vegetable;
        Vegetable vegetable2;
        VegetablePK pk = new VegetablePK("Eggplant", "Purple");
        VegetablePK pk2 = new VegetablePK("Capsicum", "Green");
        String[] tags = {"California", "DE"};
        String[] tags2 = {"Florida", "FD"};

        try {
            // Usecase for char with value ' ' (space)
            vegetable = new Vegetable();
            vegetable.setId(pk);
            vegetable.setCost(2.09);
            vegetable.setTags(tags);
            vegetable.setType(' ');
            em.persist(vegetable);

            // Usecase for char with value null
            vegetable2 = new Vegetable();
            vegetable2.setId(pk2);
            vegetable2.setCost(1.35);
            vegetable2.setTags(tags2);
            em.persist(vegetable2);

            commitTransaction(em);
        } catch (RuntimeException e) {
            if (isTransactionActive(em)){
                rollbackTransaction(em);
            }
            throw e;
        } finally {
            closeEntityManager(em);
        }

        em = createEntityManager();
        em.clear();
        clearCache();

        beginTransaction(em);
        try {
            vegetable = em.find(Vegetable.class, pk);
            vegetable2 = em.find(Vegetable.class, pk2);
            commitTransaction(em);
            assertNotNull(vegetable);
            assertNotNull(vegetable2);
            assertTrue(vegetable.getType() == '\u0000');
        } catch (RuntimeException e) {
            if (isTransactionActive(em)){
                rollbackTransaction(em);
            }
            throw e;
        } finally {
            closeEntityManager(em);
        }
    }

    // Bug 340810 - merge problem: existing object referenced by new not cascade merged if not in cache
    // Uncomment the test when the bug is fixed
/*    public void testMergeNewReferencingOldChangedClearCache() {
        internalTestMergeNewReferencingOldChanged(true);
    }*/
    // Bug 340802 - merge problem: existing object referenced by new not cascade merged
    public void testMergeNewReferencingOldChanged() {
        internalTestMergeNewReferencingOldChanged(false);
    }
    void internalTestMergeNewReferencingOldChanged(boolean shouldClearCache) {
        // create and persist Address
        Address address = new Address();
        address.setCountry("Original");
        address.setProvince("Original");
        address.setPostalCode("Original");
        address.setCity("Original");
        address.setStreet("Original");
        EntityManager em = createEntityManager();
        beginTransaction(em);
        em.persist(address);
        commitTransaction(em);
        closeEntityManager(em);

        if (shouldClearCache) {
            clearCache();
        }

        // alter the Address, Create a new Employee, assign it the Address, merge the Employee in the new EntityManager.
        address.setCountry("Updated");
        address.setProvince("Updated");
        address.setPostalCode("Updated");
        address.setCity("Updated");
        address.setStreet("Updated");
        Employee emp = new Employee();
        emp.setFirstName("New");
        emp.setAddress(address);
        address.getEmployees().add(emp);
        em = createEntityManager();
        beginTransaction(em);
        Employee empMerged = em.merge(emp);
        commitTransaction(em);
        closeEntityManager(em);

        Address addressMerged = empMerged.getAddress();

        // compare would fail unless emp also has id and version
        emp.setId(empMerged.getId());
        emp.setVersion(1);
        compareObjects(emp, empMerged);
        // compare would fail unless address has the same version as addressMerged
        address.setVersion(addressMerged.getVersion());
        compareObjects(address, addressMerged);

        verifyObjectInCacheAndDatabase(empMerged);
        verifyObjectInCacheAndDatabase(addressMerged);
    }

    // Bug 346022
    public void testAddAndDeleteSameObject(){
        EntityManager em = createEntityManager();
        beginTransaction(em);

        Employee emp = new Employee();
        emp.setFirstName("A");
        em.persist(emp);
        Project project = new SmallProject();
        project.setDescription("B");
        em.persist(project);
        emp.addProject(project);
        project.addTeamMember(emp);
        em.flush();
        em.clear();
        clearCache();
        try{
            emp = em.find(Employee.class, emp.getId());
            project = em.find(SmallProject.class, project.getId());
            emp.removeProject(project);
            project.removeTeamMember(emp);
            em.flush();

            emp.addProject(project);
            project.addTeamMember(emp);
            em.flush();

            em.clear();
            clearCache();

            emp = em.find(Employee.class, emp.getId());
            project = em.find(SmallProject.class, project.getId());

            assertTrue("Employee projects were not the correct size", emp.getProjects().size() == 1);
            assertTrue("Project did not have the correct number of team members", project.getTeamMembers().size() == 1);

        } finally {
            rollbackTransaction(em);
        }
    }

    public void testDeleteAllProjects() {
        if ((JUnitTestCase.getServerSession()).getPlatform().isSymfoware()) {
            getServerSession().logMessage("Test testDeleteAllProjects skipped for this platform, "
                     + "Symfoware doesn't support UpdateAll/DeleteAll on multi-table objects (see rfe 298193).");
            return;
        }

        String errorMsg = "";
        SmallProject sp = null;
        LargeProject lp = null;
        HugeProject hp = null;
        SpecialHugeProject slp = null;

        EntityManager em = createEntityManager();
        beginTransaction(em);
        String[] classesToDelete = {"Project", "SmallProject", "LargeProject", "HugeProject", "SpecialHugeProject"};
        try {
            for (int i=0; i < classesToDelete.length; i++) {
                if (sp == null) {
                    sp = new SmallProject();
                    em.persist(sp);
                }
                if (lp == null) {
                    lp = new LargeProject();
                    em.persist(lp);
                }
                if (hp == null) {
                    hp = new HugeProject();
                    em.persist(hp);
                }
                if (slp == null) {
                    slp = new SpecialHugeProject();
                    em.persist(slp);
                }
                em.flush();

                String classToDelete = classesToDelete[i];
                em.createQuery("DELETE FROM "+classToDelete+" p").executeUpdate();

                em.clear();

                sp = em.find(SmallProject.class, sp.getId());
                lp = em.find(LargeProject.class, lp.getId());
                hp = em.find(HugeProject.class, hp.getId());
                slp = em.find(SpecialHugeProject.class, slp.getId());

                String unexpectedlyDeleted = "";
                String unexpectedlyNotDeleted = "";
                if (sp == null) {
                    if (classToDelete.equals("LargeProject") || classToDelete.equals("HugeProject") || classToDelete.equals("SpecialHugeProject")) {
                        unexpectedlyDeleted += "SmallProject; ";
                    }
                } else {
                    if (classToDelete.equals("Project") || classToDelete.equals("SmallProject")) {
                        unexpectedlyNotDeleted += "SmallProject; ";
                    }
                }
                if (lp == null) {
                    if (classToDelete.equals("SmallProject") || classToDelete.equals("HugeProject") || classToDelete.equals("SpecialHugeProject")) {
                        unexpectedlyDeleted += "LargeProject; ";
                    }
                } else {
                    if (classToDelete.equals("Project") || classToDelete.equals("LargeProject")) {
                        unexpectedlyNotDeleted += "LargeProject; ";
                    }
                }
                if (hp == null) {
                    if (classToDelete.equals("SmallProject") || classToDelete.equals("SpecialHugeProject")) {
                        unexpectedlyDeleted += "HugeProject; ";
                    }
                } else {
                    if (classToDelete.equals("Project") || classToDelete.equals("LargeProject") || classToDelete.equals("HugeProject")) {
                        unexpectedlyNotDeleted += "HugeProject; ";
                    }
                }
                if (slp == null) {
                    if (classToDelete.equals("SmallProject")) {
                        unexpectedlyDeleted += "SpecialHugeProject; ";
                    }
                } else {
                    if (classToDelete.equals("Project") || classToDelete.equals("LargeProject")
                            || classToDelete.equals("HugeProject") || classToDelete.equals("SpecialHugeProject")) {
                        unexpectedlyNotDeleted += "SpecialHugeProject; ";
                    }
                }
                String localErrorMsg = "";
                if (unexpectedlyDeleted.length() > 0) {
                    localErrorMsg += "\n\t\tUnexpectedlyDeleted: " + unexpectedlyDeleted;
                }
                if (unexpectedlyNotDeleted.length() > 0) {
                    localErrorMsg += "\n\t\tUnexpectedlyNotDeleted: " + unexpectedlyNotDeleted;
                }
                if (localErrorMsg.length() > 0) {
                    errorMsg += "\n\tDELETE FROM "+classToDelete+" p" + localErrorMsg ;
                }
            }
        } finally {
            closeEntityManagerAndTransaction(em);
        }
        if (errorMsg.length() > 0) {
            fail(errorMsg);
        }
    }

    // Bug 348766
    public void testEMFBuiltWithSession(){
        EntityManagerFactory emf = new EntityManagerFactoryImpl(JUnitTestCase.getServerSession());
        EntityManager em = null;
        try{
            em = emf.createEntityManager(new HashMap());
        } catch (Exception e){
            fail("Exception thrown while creating entity manager with entity manager factory created from session: " + e.getMessage());
        }
        beginTransaction(em);
        Employee emp = new Employee();
        em.persist(emp);
        commitTransaction(em);
        beginTransaction(em);
        emp = em.find(Employee.class, emp.getId());
        em.remove(emp);
        commitTransaction(em);

        Exception loadingException = null;
        try{
            JpaHelper.getEntityManagerFactory(emf).refreshMetadata(new HashMap());
        } catch (PersistenceUnitLoadingException e){
            loadingException = e;
        }
        if (loadingException == null){
            fail("Proper exception not thrown when refreshing metadata: ");
        }
    }

    public void testLazyOneToOneFetchInitialization() {
        if (!isWeavingEnabled()) {
            return;
        }
        EntityManager em = createEntityManager();
        Room room = null;
        try {
            beginTransaction(em);
            room = new Room();
            room.setId(1);
            room.setLength(20);
            room.setHeight(10);
            room.setWidth(18);

            Door east = new Door();
            east.setId(100);
            east.setHeight(8);
            east.setWidth(5);
            int year = 2013;
            int month = 1;
            int day = 30;
            east.setSaleDate(Helper.dateFromYearMonthDate(year, month - 1, day));
            east.setRoom(room);
            room.addDoor(east);

            em.persist(room);
            commitTransaction(em);
        } catch (RuntimeException ex) {
            if (isTransactionActive(em)) {
                rollbackTransaction(em);
            }
            fail("Failed to create data for testLazyOneToOneFetchInitialization");
        } finally {
            closeEntityManager(em);
        }

        em = createEntityManager();

        try {
            beginTransaction(em);
            Door d = em.find(Door.class, 100);
            assertTrue("Lazy Field has been initialized referencing to an object of shared cache", d.isRoomInstanceInitialized());
            // Trigger indirection to fetch the object and verify that it has been
            // initialized with correct value.
            Room r = d.getRoom();
            assertTrue("Unable to fetch the lazy field.", r != null);
            assertTrue("The lazy field has been fetched incorrectly", r.equals(room));
        } catch (RuntimeException ex) {
            fail("Failed to fetch data for testLazyOneToOneFetchInitialization");
        } finally {
            if (isTransactionActive(em)) {
                rollbackTransaction(em);
            }
            closeEntityManager(em);
        }
    }

    //Bug#457480 :Load data, call flush() to force a refresh,
    //remove a loaded entity to simulate "not loaded" and query
    public void testForNPEInCloning() {
        if (!isWeavingEnabled()) {
            return;
        }
        EntityManager em = createEntityManager();
        Hinge hinge1;
        Hinge hinge2;
        Door east;
        try {
            beginTransaction(em);

            hinge1 = new Hinge();
            hinge1.setId(1);

            hinge2 = new Hinge();
            hinge2.setId(2);

            east = new Door();
            east.setId(102);
            east.setSaleDate(Helper.dateFromYearMonthDate(2013, 1, 20));

            hinge1.setDoor(east);
            hinge2.setDoor(east);
            em.persist(hinge1);
            em.persist(hinge2);

            commitTransaction(em);
        } catch (RuntimeException ex) {
            if (isTransactionActive(em)) {
                rollbackTransaction(em);
            }
            fail("Failed to create data for testForNPEInCloning" + ex);
            return;
        } finally {
            closeEntityManager(em);
        }

        em = createEntityManager();

        try {
            beginTransaction(em);
            //Persist any entity to enable flush()
            Room room = new Room();
            room.setId(3);
            em.persist(room);

            em.flush();
            // The bug exhibits itself in a fresh session where this specific CacheKey isn't loaded yet.
            // To simulate this condition, removing from cache.
            Session session = em.unwrap(DatabaseSession.class);
            session.getIdentityMapAccessor().removeFromIdentityMap(session.getId(hinge2), Hinge.class);

            TypedQuery<Hinge> q = em.createNamedQuery("loadHinges", Hinge.class);
            q.setParameter("doorid", east.getId());
            q.setHint(QueryHints.LEFT_FETCH, "h.door");
            List<Hinge> hinges = q.getResultList();
            Assert.assertEquals(2, hinges.size());
        } catch (Exception e) {
            fail("Failed testForNPEInCloning due to " + e);
        } finally {
            if (isTransactionActive(em)) {
                rollbackTransaction(em);
            }
            try {
                //cleanup persisted entities
                beginTransaction(em);
                hinge1 = em.merge(hinge1);
                hinge2 = em.merge(hinge2);
                east = em.merge(east);
                if (hinge1 != null)
                    em.remove(hinge1);
                if (hinge2 != null)
                    em.remove(hinge2);
                if (east != null)
                    em.remove(east);

                commitTransaction(em);
            } catch (Exception e) {
               //Do nothing.  This is cleanup code
            } finally {
                if (isTransactionActive(em)){
                    rollbackTransaction(em);
                }
            }
            closeEntityManager(em);
        }
    }

    /*Bug#438193: Test for proxy object not being loaded during commit.  Prior to the fix, the proxy object
     * could get loaded from the DB during commit due to RepeatableWriteUnitOfWork.discoverUnregisteredNewObjects()
     * invoking the object's hashCode() */
    public void testProxyFetchDuringCommit() {
        if (!isWeavingEnabled()) {
            return;
        }

        Door door1 = null;
        Room room1 = null;
        EntityManager em = createEntityManager();
        try {
            beginTransaction(em);
            //persist door
            door1 = new Door();
            door1.setId(11);
            door1.setHeight(84);
            door1.setWidth(48);
            int year = 2013;
            int month = 1;
            int day = 30;
            door1.setSaleDate(Helper.dateFromYearMonthDate(year, month - 1, day));
            em.persist(door1);

            //persist room
            room1 = new Room();
            room1.setId(12);
            room1.setLength(20);
            room1.setHeight(10);
            room1.setWidth(18);
            em.persist(room1);
            commitTransaction(em);
        } catch (RuntimeException e) {
            throw e;
        } finally {
            closeEntityManager(em);
            clearCache();
        }

        Door door2 = null;
        Room room2 = null;
        try {
            em = createEntityManager();
            beginTransaction(em);
            //find door
            door2 = em.find(Door.class, door1.getId());
            //update door with reference to room
            room2 = em.getReference(Room.class, room1.getId());
            door2.setRoom(room2);
            commitTransaction(em);
            //Cannot check if proxy is loaded with ProviderUtil.  Hence below call room2.isHeightSetGreaterThanZero() is
            //added which uses introspection to get the value of the room's height attribute
            assertFalse("Room is LOADED", room2.isHeightSetGreaterThanZero());
        } catch (RuntimeException e) {
            // Re-throw exception to ensure stacktrace appears in test result.
            throw e;
        } finally {
            if (isTransactionActive(em)){
                rollbackTransaction(em);
            }
            //cleanup persisted entities
            try {
                //cleanup persisted entities
                if (door1 != null) {
                    beginTransaction(em);
                    door1 = em.find(Door.class, door1.getId());
                    em.remove(door1);
                    commitTransaction(em);
                }
            } catch (Exception e) {
               //Do nothing.  This is cleanup code
            } finally {
                if (isTransactionActive(em)){
                    rollbackTransaction(em);
                }
                closeEntityManager(em);
            }
        }
    }

    // Bug 368653
    public void testSequenceObjectWithSchemaName(){
        // platform that supports sequence objects is required for this test
        // properties work only in Java SE
        if(!getServerSession().getPlatform().supportsSequenceObjects() || isOnServer()) {
            return;
        }

        // Avoid test on certain platforms due to Bug 370487
        if (getServerSession().getPlatform().isDerby() || getServerSession().getPlatform().isDB2() || getServerSession().getPlatform().isPostgreSQL()){
            return;
        }

        // close the entire factory in order to set the session customizer
        closeEntityManagerFactory();
        Map<String, String> properties = new HashMap<String, String>();
        properties.putAll(TableQualifierSessionCustomizer.database_properties);
        properties.put(PersistenceUnitProperties.SESSION_CUSTOMIZER, TableQualifierSessionCustomizer.class.getName());
        EntityManager em = createEntityManager(properties);

        beginTransaction(em);
        Address address = new Address();
        try {
            em.persist(address);
            commitTransaction(em);
            // no exception thrown -> passed

            // clean-up
            beginTransaction(em);
            em.createNativeQuery("DELETE FROM CMP3_ADDRESS WHERE ADDRESS_ID = " + address.getID()).executeUpdate();
            commitTransaction(em);
        } catch (RuntimeException exception) {
            if (isTransactionActive(em)) {
                rollbackTransaction(em);
            }
            throw exception;
        } finally {
            closeEntityManager(em);
            // close the entire factory in order to clean up the session customizer
            closeEntityManagerFactory();
        }
    }

    public void testSharedExpressionInQueries() {
        // the test spawns threads.
        if (isOnServer()) {
            return;
        }
        getServerSession().getProject().getJPQLParseCache().getCache().clear();

        EntityManager em = createEntityManager();
        Query query = em.createQuery("SELECT e FROM Employee e");
        query.getResultList();
        em.close();
        Runnable[] runnables = {
            new Runnable() {
            @Override
            public void run(){
                EntityManager em = createEntityManager();
                Query query = em.createQuery("SELECT e FROM Employee e");
                query.getResultList();
                em.close();
            };},
            new Runnable() {
            @Override
            public void run(){
                EntityManager em = createEntityManager();
                Query query = em.createQuery("SELECT e FROM Employee e");
                query.setHint(QueryHints.FETCH, "e.manager");
                query.getResultList();
                em.close();
            };},
            new Runnable() {
            @Override
            public void run(){
                EntityManager em = createEntityManager();
                Query query = em.createQuery("SELECT e FROM Employee e");
                query.setHint(QueryHints.FETCH, "e.address");
                query.getResultList();
                em.close();
            };},
            new Runnable() {
            @Override
            public void run(){
                EntityManager em = createEntityManager();
                Query query = em.createQuery("SELECT e FROM Employee e");
                query.setHint(QueryHints.FETCH, "e.manager");
                query.setHint(QueryHints.FETCH, "e.address");
                query.getResultList();
                em.close();
            };},
            new Runnable() {
            @Override
            public void run(){
                EntityManager em = createEntityManager();
                Query query = em.createQuery("SELECT e FROM Employee e");
                query.setHint(QueryHints.FETCH, "e.manager");
                query.setHint(QueryHints.FETCH, "e.address");
                query.setHint(QueryHints.FETCH, "e.projects.teamLeader");
                query.getResultList();
                em.close();
            };},
            new Runnable() {
            @Override
            public void run(){
                EntityManager em = createEntityManager();
                Query query = em.createQuery("SELECT e FROM Employee e");
                query.setHint(QueryHints.FETCH, "e.address");
                query.setHint(QueryHints.FETCH, "e.manager");
                query.setHint(QueryHints.FETCH, "e.projects.teamMembers");
                query.getResultList();
                em.close();
            };},
            new Runnable() {
            @Override
            public void run(){
                EntityManager em = createEntityManager();
                Query query = em.createQuery("SELECT e FROM Employee e");
                query.setHint(QueryHints.FETCH, "e.managedEmployees");
                query.getResultList();
                em.close();
            };},
            new Runnable() {
            @Override
            public void run(){
                EntityManager em = createEntityManager();
                Query query = em.createQuery("SELECT e FROM Employee e");
                query.setHint(QueryHints.FETCH, "e.responsibilities");
                query.getResultList();
                em.close();
            };},
            new Runnable() {
            @Override
            public void run(){
                EntityManager em = createEntityManager();
                Query query = em.createQuery("SELECT e FROM Employee e");
                query.setHint(QueryHints.FETCH, "e.phoneNumbers");
                query.getResultList();
                em.close();
            };},
            new Runnable() {
            @Override
            public void run(){
                EntityManager em = createEntityManager();
                Query query = em.createQuery("SELECT e FROM Employee e");
                query.setHint(QueryHints.FETCH, "e.dealers");
                query.getResultList();
                em.close();
            };},
        };

        Thread[] threads = new Thread[runnables.length];
        Exception exceptions[] = new Exception[runnables.length];
        for (int i=0; i < runnables.length; i++) {
            threads[i] = new Thread(runnables[i], Integer.toString(i));
        }

        for (int i=0; i < runnables.length; i++) {
            threads[i].start();
        }

        boolean exceptionInThread = false;
        for (int i=0; i < runnables.length; i++) {
            try {
                threads[i].join();
            } catch (Exception ex) {
                exceptionInThread = true;
                exceptions[i] = ex;
            }
        }

        if (exceptionInThread) {
            String errorMsg = "";
            for (int i=0; i < exceptions.length; i++) {
                if (exceptions[i] != null) {
                    errorMsg += i + ": " + exceptions[i] + "\n";
                }
            }
            fail(errorMsg);
        }
    }

    public static class TableQualifierSessionCustomizer implements SessionCustomizer {
        public static Map<String, String> database_properties = JUnitTestCaseHelper.getDatabaseProperties();

        @Override
        public void customize(Session session) throws Exception {
            String schema = getCurrentSchemaName(session);
            session.getPlatform().setTableQualifier(schema);
        }
    }

    protected static String getCurrentSchemaName(Session session) {
        Map<String, String> properties = TableQualifierSessionCustomizer.database_properties;
        String driver = properties.get(PersistenceUnitProperties.JDBC_DRIVER);
        String url = properties.get(PersistenceUnitProperties.JDBC_URL);
        String user = properties.get(PersistenceUnitProperties.JDBC_USER);
        String pw = properties.get(PersistenceUnitProperties.JDBC_PASSWORD);

        DataSource dataSource = new TestDataSource(driver, url, new Properties());
        Connection conn = null;
        try {
            conn = dataSource.getConnection(user, pw);
            PreparedStatement stmt = conn.prepareStatement("SELECT ADDRESS_ID FROM CMP3_ADDRESS WHERE ADDRESS_ID = 1");
            ResultSet rs = stmt.executeQuery();
            String schema = rs.getMetaData().getSchemaName(1);
            return schema;
        } catch (SQLException e) {
            throw new RuntimeException(e);
        } finally {
            try {
                if (conn != null) {
                    conn.close();
                }
            } catch (SQLException e) {
                //ignore exception
            }
        }
    }

    // Bug 370474 - in a joined inheritance hierarchy, base class OneToMany relationship, query using join fetch works once then fails
    public void testInheritanceFetchJoinSecondCall() {
        EntityManager em = createEntityManager();
        LargeProject project = new LargeProject();
        project.setName("InheritanceFetchJoinSecondCall");
        beginTransaction(em);
        try {
            // should have at least one project
            em.persist(project);
            em.flush();
            TypedQuery<LargeProject> queryFetchOne = em.createQuery("SELECT p FROM LargeProject p JOIN FETCH p.teamLeader", LargeProject.class);
            TypedQuery<LargeProject> queryFetchMany = em.createQuery("SELECT p FROM LargeProject p JOIN FETCH p.teamMembers", LargeProject.class);
            em.clear();
            // first time works
            queryFetchOne.getResultList();
            em.clear();
            // second time used to fail
            queryFetchOne.getResultList();
            em.clear();
            // first time works
            queryFetchMany.getResultList();
            em.clear();
            // second time used to fail
            queryFetchMany.getResultList();
        } finally {
            rollbackTransaction(em);
            closeEntityManager(em);
        }
    }

    // Bug 384607
    public void testReplaceElementCollection(){
        EntityManager em = createEntityManager();
        beginTransaction(em);
        Golfer golfer = new Golfer();
        GolferPK pk = new GolferPK(102);
        WorldRank rank = new WorldRank();
        rank.setId(102);
        golfer.setWorldRank(rank);
        golfer.getSponsorDollars().put("Oracle", 10000);
        golfer.setGolferPK(pk);
        em.persist(golfer);
        em.persist(rank);
        em.flush();

        golfer = em.find(Golfer.class, golfer.getGolferPK());
        golfer.getSponsorDollars().put("Callaway", 20000);
        em.flush();

        clearCache();
        em.clear();

        golfer = em.find(Golfer.class, golfer.getGolferPK());
        assertTrue("Incorrect Number of sponsors", golfer.getSponsorDollars().size() == 2);
        assertTrue("Missing Sponsor: Callaway", golfer.getSponsorDollars().get("Callaway").equals(20000));
        assertTrue("Missing Sponsor: Oracle", golfer.getSponsorDollars().get("Oracle").equals(10000));

        golfer = em.find(Golfer.class, golfer.getGolferPK());
        golfer.setSponsorDollars(new HashMap<String, Integer>());
        em.flush();

        clearCache();
        em.clear();

        golfer = em.find(Golfer.class, golfer.getGolferPK());
        assertTrue("Incorrect Number of sponsors", golfer.getSponsorDollars().size() == 0);

        rollbackTransaction(em);
    }

    // Bug 414801 - Merge does not merge cascade all mappings
    public void testUpdateDetachedEntityWithRelationshipCascadeRefresh() {
        Canoe canoeTD = null;
        Lake lakeTD = null;
        try {
            // Create test data
            EntityManager em = createEntityManager();
            beginTransaction(em);

            canoeTD = new Canoe();
            canoeTD.setColor("Red");
            lakeTD = new Lake();
            lakeTD.setName("Bob's Lake");
            canoeTD.setLake(lakeTD);
            em.persist(canoeTD);

            commitTransaction(em);
            closeEntityManager(em);

            clearCache();

            // Initial refreshing query
            em = createEntityManager();

            Query query1 = em.createQuery("select c from Canoe c where c.id = :id");
            query1.setHint(QueryHints.REFRESH, HintValues.TRUE);
            query1.setParameter("id", canoeTD.getId());

            Canoe canoe = (Canoe)query1.getSingleResult();
            assertNotNull("Entity queried (Canoe) with id " + canoeTD.getId() + " should not be null", canoe);
            Lake lake = canoe.getLake();
            assertNotNull("Canoe->Lake for Canoe id " + canoeTD.getId() + " should be non-null", lake);

            closeEntityManager(em);

            // change the value on the detached Lake
            String newName = "Doug's Lake";
            lake.setName(newName);

            // merge the modified detached canoe
            em = createEntityManager();
            beginTransaction(em);
            Canoe mergedCanoe = em.merge(canoe);
            commitTransaction(em);
            closeEntityManager(em);

            // the merged canoe's lake should be the 'new' name
            assertEquals("Canoe->Lake.name should be changed", newName, mergedCanoe.getLake().getName());
        } finally {
            // clean up test data
            if (canoeTD != null) {
                EntityManager em = createEntityManager();
                Canoe canoe = em.find(Canoe.class, canoeTD.getId());
                if (canoe != null) {
                    beginTransaction(em);
                    canoe = em.merge(canoe);
                    em.remove(canoe);
                    em.remove(canoe.getLake());
                    commitTransaction(em);
                }
                closeEntityManager(em);
            }
        }
    }

    //Bug#463350
    public void testCopy() {
        EntityManager em = null;
        Job job = new ConcreteJob();
        CopyGroup eventsCG = new CopyGroup();
        eventsCG.addAttribute("id");
        eventsCG.addAttribute("datef");
        CopyGroup jobCG = new CopyGroup();
        jobCG.addAttribute("id");
        eventsCG.addAttribute("job", jobCG);
        jobCG.addAttribute("events", eventsCG);

        try {
            em = createEntityManager();
            beginTransaction(em);
            em.persist(job);
            em.flush();
            job = (Job) em.unwrap(JpaEntityManager.class).copy(job, jobCG);
            commitTransaction(em);

            for (int i = 0; i < 10; i++) {
                beginTransaction(em);
                job = em.merge(job);
                em.flush();
                Event e = new Event();
                e.setJob(job);
                job.getEvents().add(e);
                em.flush();

                CopyGroup eventsCG2 = new CopyGroup();
                eventsCG2.addAttribute("id");
                eventsCG2.addAttribute("datef");
                CopyGroup jobCG2 = new CopyGroup();
                jobCG2.addAttribute("id");
                eventsCG2.addAttribute("job", jobCG2);
                jobCG2.addAttribute("events", eventsCG2);

                job = (Job) em.unwrap(JpaEntityManager.class).copy(job, jobCG2);
                commitTransaction(em);
            }
        } finally {
            if (em != null) {
                closeEntityManagerAndTransaction(em);
            }
        }
    }

    /**
     * Bug #476018
     * This test verifies that EclipseLink prints server detection related log
     * messages at appropriate level - FINE in session log, FINER in other cases
     */
    public void testServerDetectionLogging(){
        if (isOnServer()) {
            return;
        }
        closeEntityManagerFactory();

        SessionLog original = AbstractSessionLog.getLog();
        try {
            AbstractSessionLog.setLog(new LogWrapper());
            //check session log for "Configured server platform message"
            Map<String, Object> properties = new HashMap<>();
            properties.putAll(JUnitTestCaseHelper.getDatabaseProperties());
            properties.put(PersistenceUnitProperties.LOGGING_LEVEL, original.getLevelString());
            properties.put(PersistenceUnitProperties.LOGGING_LOGGER, LogWrapper.class.getName());
            EntityManagerFactoryImpl emf = (EntityManagerFactoryImpl) Persistence.createEntityManagerFactory(getPersistenceUnitName(), properties);
            emf.refreshMetadata(properties);
            SimpleSessionLogWrapper wr = (SimpleSessionLogWrapper) emf.getServerSession().getSessionLog();
            assertEquals("configured_server_platform should be printed at FINE level",
                    wr.getLevel() <= SessionLog.FINE, wr.expected());

            //it may happen that logging is not fully configured as that happens
            //after detecting server platform; in such case, messages are printed out
            //by an instance of DefaultSessionLog
            LogWrapper lw = new LogWrapper("detect_server_platform");
            AbstractSessionLog.setLog(lw);
            AbstractSessionLog.getLog().setSession(null);
            lw.setSession(null);
            ServerPlatformUtils.detectServerPlatform(null);
            assertEquals("detect_server_platform should be printed at FINER level",
                    lw.getLevel() <= SessionLog.FINER, lw.expected());

            lw = new LogWrapper("detect_server_platform");
            AbstractSessionLog.setLog(lw);
            Session ss = wr.getSession();
            AbstractSessionLog.getLog().setSession(ss);
            AbstractSessionLog.getLog().getSession().setSessionLog(lw);
            lw.setSession(ss);
            ServerPlatformUtils.detectServerPlatform((ServerSession) ss);
            assertEquals("detect_server_platform should be printed at FINER level",
                    lw.getLevel() <= SessionLog.FINER, lw.expected());
        } finally {
            AbstractSessionLog.setLog(original);
            closeEntityManagerFactory();
        }
    }

    public void testDetachChildObjects() {
    	EntityManager em = createEntityManager();
    	beginTransaction(em);
		InitTestDetachChildObjects(em);
		UnitOfWorkImpl uow = (UnitOfWorkImpl) em.unwrap(JpaEntityManager.class).getActiveSession();

		Material mat = em.find(Material.class, 1L);
		mat.setWert("WERT3");
		MaterialEreignis matEreignis1 = new MaterialEreignis();
		matEreignis1.setChangedObject(mat);
		matEreignis1.setBeforeChange(mat.getLastHist());
		MaterialHist afterMat1 = makeHistCopy(mat);
		matEreignis1.setAfterChange(afterMat1);

		em.persist(matEreignis1);
		em.flush();
		em.detach(matEreignis1);
		
		List<PlanArbeitsgangHist> pagList = getInstancesFromPC(PlanArbeitsgangHist.class, uow);
		assertTrue(pagList.isEmpty());
		for (PlanArbeitsgangHist pag : pagList) {
			assertTrue(em.contains(pag));
		}
		rollbackTransaction(em);
		closeEntityManager(em);
    }

    public void testAutoCloseable() {
        EntityManagerFactory emfOuter = null;
        EntityManager emOuter = null;
        try (JpaEntityManagerFactory emf = (JpaEntityManagerFactory) Persistence.createEntityManagerFactory(getPersistenceUnitName(), JUnitTestCaseHelper.getDatabaseProperties());
                JpaEntityManager em = (JpaEntityManager) emf.createEntityManager()) {
            emfOuter = emf;
            emOuter = em;
            assertNotNull(emf);
            assertNotNull(em);
            assertTrue(emOuter.isOpen());
            assertTrue(emfOuter.isOpen());
        } finally {
            assertFalse(emOuter.isOpen());
            assertFalse(emfOuter.isOpen());
        }
    }

    private void InitTestDetachChildObjects(EntityManager em) {
        // test data - manual creation
        try {
            em.createNativeQuery("INSERT INTO MATERIAL (ID, VERSION, IDENT, WERT) VALUES (1, 1, 'MAT', 'WERT2')").executeUpdate();
			em.createNativeQuery("INSERT INTO MATERIALHIST (ID, VERSION, IDENT, WERT, ORIGINAL_ID) VALUES (1, 1, 'MAT', 'WERT1', 1)").executeUpdate();
			em.createNativeQuery("INSERT INTO MATERIALHIST (ID, VERSION, IDENT, WERT, ORIGINAL_ID) VALUES (2, 1, 'MAT', 'WERT2', 1)").executeUpdate();
			em.createNativeQuery("INSERT INTO PLANARBEITSGANG (ID, VERSION, NAME, MATERIAL_ID) VALUES (1, 1, 'PAG1', 1)").executeUpdate();
			em.createNativeQuery("INSERT INTO PLANARBEITSGANG (ID, VERSION, NAME, MATERIAL_ID) VALUES (2, 1, 'PAG2', 1)").executeUpdate();
			em.createNativeQuery("INSERT INTO PLANARBEITSGANGHIST (ID, VERSION, NAME, MATERIAL_ID, ORIGINAL_ID) VALUES (1, 1, 'PAG1', 1, 1)").executeUpdate();
			em.createNativeQuery("INSERT INTO PLANARBEITSGANGHIST (ID, VERSION, NAME, MATERIAL_ID, ORIGINAL_ID) VALUES (2, 1, 'PAG2', 1, 2)").executeUpdate();
			em.createNativeQuery("INSERT INTO PLANARBEITSGANGHIST (ID, VERSION, NAME, MATERIAL_ID, ORIGINAL_ID) VALUES (3, 1, 'PAG1', 2, 1)").executeUpdate();
			em.createNativeQuery("INSERT INTO PLANARBEITSGANGHIST (ID, VERSION, NAME, MATERIAL_ID, ORIGINAL_ID) VALUES (4, 1, 'PAG2', 2, 2)").executeUpdate();
			em.createNativeQuery("UPDATE MATERIAL SET LASTHIST_ID = 2 WHERE ID = 1").executeUpdate();
			em.createNativeQuery("UPDATE PLANARBEITSGANG SET LASTHIST_ID = 3 WHERE ID = 1").executeUpdate();
			em.createNativeQuery("UPDATE PLANARBEITSGANG SET LASTHIST_ID = 4 WHERE ID = 2").executeUpdate();
			em.createNativeQuery("INSERT INTO MATERIALEREIGNIS (ID, VERSION, AFTERCHANGE_ID, BEFORECHANGE_ID, CHANGEDOBJECT_ID) VALUES (1, 1, 2, 1, 1)").executeUpdate();
        } catch (Exception e) {
            fail("Error creating test data: " + e.getMessage());
        } 
    }
    private MaterialHist makeHistCopy(Material mat) {
		MaterialHist histCopy = new MaterialHist();
		mat.setLastHist(histCopy);
		histCopy.setOriginal(mat);
		histCopy.setIdent(mat.getIdent());
		histCopy.setWert(mat.getWert());
		for (PlanArbeitsgang pag : mat.getRestproduktionsweg()) {
			PlanArbeitsgangHist pagHistCopy = new PlanArbeitsgangHist();
			pagHistCopy.setName(pag.getName());
			pagHistCopy.setOriginal(pag);
			pag.setLastHist(pagHistCopy);
			histCopy.getRestproduktionsweg().add(pagHistCopy);
			pagHistCopy.setMaterial(histCopy);
		}
		return histCopy;
	}

	@SuppressWarnings("unchecked")
	private <T> List<T> getInstancesFromPC(Class<T> type, UnitOfWorkImpl uow) {
		Set<Object> pc = uow.getCloneMapping().keySet();
		List<T> result = new ArrayList<>();
		for (Object o : pc) {
			if (type.isInstance(o)) {
				result.add((T) o);
			}
		}
		return result;
	}

    public static final class Platform extends ServerPlatformBase {

        public Platform(DatabaseSession newDatabaseSession) {
            super(newDatabaseSession);
        }

        @Override
        public Class getExternalTransactionControllerClass() {
            return null;
        }
    }
}
