| /* |
| * Copyright (c) 1998, 2021 Oracle and/or its affiliates. All rights reserved. |
| * |
| * This program and the accompanying materials are made available under the |
| * terms of the Eclipse Public License v. 2.0 which is available at |
| * http://www.eclipse.org/legal/epl-2.0, |
| * or the Eclipse Distribution License v. 1.0 which is available at |
| * http://www.eclipse.org/org/documents/edl-v10.php. |
| * |
| * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause |
| */ |
| |
| // Contributors: |
| // Oracle - initial API and implementation from Oracle TopLink |
| package org.eclipse.persistence.testing.tests.distributedservers.rcm; |
| |
| import java.util.Enumeration; |
| import java.util.Hashtable; |
| |
| import org.eclipse.persistence.descriptors.ClassDescriptor; |
| import org.eclipse.persistence.internal.sessions.UnitOfWorkImpl; |
| import org.eclipse.persistence.queries.DatabaseQuery; |
| import org.eclipse.persistence.queries.ReadObjectQuery; |
| import org.eclipse.persistence.sessions.UnitOfWork; |
| import org.eclipse.persistence.testing.tests.distributedservers.DistributedServer; |
| import org.eclipse.persistence.testing.tests.distributedservers.DistributedServersModel; |
| import org.eclipse.persistence.testing.framework.TestErrorException; |
| import org.eclipse.persistence.testing.models.employee.domain.Address; |
| import org.eclipse.persistence.testing.models.employee.domain.Employee; |
| |
| /** |
| * Tests fix for bug:3604593 |
| * This test checks to see that when changing an object's reference that |
| * removing a referenced object in the database will not cause a corruption |
| * when the original changeset containing the reference change gets propogated. |
| */ |
| public class InvalidateObjectWithMissingReferenceTest extends ConfigurableCacheSyncDistributedTest { |
| ReadObjectQuery query; |
| Employee originalObject; |
| Address originalAddress; |
| Address newAddress; |
| DistributedServer server; |
| |
| public InvalidateObjectWithMissingReferenceTest() { |
| super(); |
| setName("InvalidateObjectWithMissingReferenceTest"); |
| cacheSyncConfigValues.put(Employee.class, ClassDescriptor.SEND_OBJECT_CHANGES); |
| cacheSyncConfigValues.put(Address.class, ClassDescriptor.DO_NOT_SEND_CHANGES); |
| } |
| |
| @Override |
| public void reset() { |
| getSession().getIdentityMapAccessor().initializeAllIdentityMaps(); |
| Enumeration enumtr = DistributedServersModel.getDistributedServers().elements(); |
| while (enumtr.hasMoreElements()) { |
| (((DistributedServer)enumtr.nextElement()).getDistributedSession()).getIdentityMapAccessor().initializeAllIdentityMaps(); |
| } |
| Enumeration keys = oldCacheSyncConfigValues.keys(); |
| while (keys.hasMoreElements()) { |
| Class<?> keyClass = (Class)keys.nextElement(); |
| ClassDescriptor descriptor = getSession().getDescriptor(keyClass); |
| int newCacheSyncType = (Integer) oldCacheSyncConfigValues.get(keyClass); |
| descriptor.setCacheSynchronizationType(newCacheSyncType); |
| } |
| } |
| |
| @Override |
| public void setup() { |
| oldCacheSyncConfigValues = new Hashtable(); |
| Enumeration keys = cacheSyncConfigValues.keys(); |
| while (keys.hasMoreElements()) { |
| Class<?> keyClass = (Class)keys.nextElement(); |
| ClassDescriptor descriptor = getSession().getDescriptor(keyClass); |
| |
| if (descriptor != null) { |
| int cacheSyncType = descriptor.getCacheSynchronizationType(); |
| Object newCacheSyncType = cacheSyncConfigValues.get(keyClass); |
| if (newCacheSyncType != null) { |
| oldCacheSyncConfigValues.put(keyClass, cacheSyncType); |
| descriptor.setCacheSynchronizationType((Integer) newCacheSyncType); |
| } |
| } |
| } |
| getSession().getIdentityMapAccessor().initializeAllIdentityMaps(); |
| |
| this.originalObject = (Employee)getSession().readObject(Employee.class); |
| this.originalAddress = this.originalObject.getAddress(); |
| this.query = new ReadObjectQuery(); |
| this.query.setSelectionObject(this.originalObject); |
| this.server = (DistributedServer)DistributedServersModel.getDistributedServers().get(0); |
| getEmployeeFromDistributedSession(this.query); |
| } |
| |
| |
| @Override |
| protected void test() { |
| |
| UnitOfWork uow = getSession().acquireUnitOfWork(); |
| |
| Employee empClone = (Employee)uow.registerObject(this.originalObject); |
| |
| this.newAddress = new Address(); |
| this.newAddress.setCity("Ottawa"); |
| this.newAddress.setPostalCode("K5J2B5"); |
| this.newAddress.setProvince("ONT"); |
| this.newAddress.setStreet("should not exist when test completes"); |
| this.newAddress.setCountry("Canada"); |
| Address addressClone = (Address)uow.registerObject(this.newAddress); |
| empClone.setAddress(addressClone); |
| uow.assignSequenceNumber(addressClone); |
| //uow.commit() is broken into components to allow DB change before cache synch propogates changes |
| ((UnitOfWorkImpl)uow).issueSQLbeforeCompletion(); |
| getAbstractSession().insertObject(this.originalAddress); |
| |
| getAbstractSession().getSessionForClass(Employee.class).executeNonSelectingSQL("UPDATE EMPLOYEE SET ADDR_ID = " + this.originalAddress.getId() + " WHERE (EMP_ID = " + empClone.getId() + ")"); |
| |
| getAbstractSession().deleteObject(addressClone); |
| |
| ((UnitOfWorkImpl)uow).mergeClonesAfterCompletion(); |
| } |
| |
| |
| @Override |
| protected void verify() { |
| Employee remoteEmployee = (Employee)getObjectFromDistributedCache(this.originalObject); |
| if ((remoteEmployee != null) && (remoteEmployee.getAddress() == null)) { |
| throw new TestErrorException("Employee's Address reference was corrupted during RCM synch" + " when Address was removed from the database. "); |
| } |
| remoteEmployee = getEmployeeFromDistributedSession(this.query); |
| if (remoteEmployee.getAddress() == null) { |
| throw new TestErrorException("Employee's Address reference was corrupted during RCM synch" + " when Address was removed from the database. "); |
| } |
| if (remoteEmployee.getAddress().getId() == newAddress.getId()) { |
| throw new TestErrorException("New object Address was built/sent with the changeset in RCM " + "though its descriptor specifies DO_NOT_SEND_CHANGES"); |
| } |
| |
| } |
| |
| |
| public Employee getEmployeeFromDistributedSession(DatabaseQuery query) { |
| try { |
| Employee result = (Employee)this.server.getDistributedSession().executeQuery(query); |
| result.getAddress(); |
| return result; |
| } catch (Exception exception) { |
| return null; |
| } |
| } |
| |
| |
| } |