Search in sources :

Example 6 with CopyGroup

use of org.eclipse.persistence.sessions.CopyGroup in project eclipselink by eclipse-ee4j.

the class EntityManagerJUnitTestSuite method testCopy.

// 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);
        }
    }
}
Also used : EntityManager(jakarta.persistence.EntityManager) JpaEntityManager(org.eclipse.persistence.jpa.JpaEntityManager) JpaEntityManager(org.eclipse.persistence.jpa.JpaEntityManager) CopyGroup(org.eclipse.persistence.sessions.CopyGroup) ConcreteJob(org.eclipse.persistence.testing.models.jpa.advanced.ConcreteJob) Event(org.eclipse.persistence.testing.models.jpa.advanced.Event) SessionEvent(org.eclipse.persistence.sessions.SessionEvent) Job(org.eclipse.persistence.testing.models.jpa.advanced.Job) ConcreteJob(org.eclipse.persistence.testing.models.jpa.advanced.ConcreteJob)

Example 7 with CopyGroup

use of org.eclipse.persistence.sessions.CopyGroup in project eclipselink by eclipse-ee4j.

the class EntityManagerJUnitTestSuite method internalTestChangeRecordKeepOldValue.

public void internalTestChangeRecordKeepOldValue(boolean addSecondStep) {
    if (isOnServer()) {
        // the test relies upon keeping attached objects between transactions.
        return;
    }
    DatabaseSessionImpl dbs = getDatabaseSession();
    ChangeRecordKeepOldValueListener listener = new ChangeRecordKeepOldValueListener();
    dbs.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();
        dbs.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 = dbs.getDescriptor(original);
            if (!descriptor.isAggregateDescriptor()) {
                Object backup = entry.getValue();
                if (original == backup) {
                    fail("Test problem: backup failed: original == backup: " + original);
                }
                if (!dbs.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();
        dbs.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<Map.Entry<Object, org.eclipse.persistence.internal.sessions.ObjectChangeSet>> itChangeSets = ((org.eclipse.persistence.internal.sessions.UnitOfWorkChangeSet) listener.uowChangeSet).getCloneToObjectChangeSet().entrySet().iterator();
        while (itChangeSets.hasNext()) {
            Map.Entry<Object, org.eclipse.persistence.internal.sessions.ObjectChangeSet> entry = itChangeSets.next();
            Object object = entry.getKey();
            ClassDescriptor descriptor = dbs.getDescriptor(object);
            if (!descriptor.isAggregateDescriptor()) {
                org.eclipse.persistence.internal.sessions.ObjectChangeSet changeSet = entry.getValue();
                if (!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<Object, org.eclipse.persistence.internal.sessions.ObjectChangeSet> entry = itChangeSets.next();
            Object object = entry.getKey();
            ClassDescriptor descriptor = dbs.getDescriptor(object);
            if (!descriptor.isAggregateDescriptor()) {
                ObjectChangeSet changeSet = entry.getValue();
                if (!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 (!dbs.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 = dbs.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);
        // 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 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 (!dbs.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);
        dbs.getEventManager().removeListener(listener);
    }
}
Also used : SmallProject(org.eclipse.persistence.testing.models.jpa.composite.advanced.member_3.SmallProject) UnitOfWork(org.eclipse.persistence.sessions.UnitOfWork) RepeatableWriteUnitOfWork(org.eclipse.persistence.internal.sessions.RepeatableWriteUnitOfWork) ObjectChangeSet(org.eclipse.persistence.internal.sessions.ObjectChangeSet) Set(java.util.Set) HashSet(java.util.HashSet) UnitOfWorkChangeSet(org.eclipse.persistence.sessions.changesets.UnitOfWorkChangeSet) Address(org.eclipse.persistence.testing.models.jpa.composite.advanced.member_1.Address) ClassDescriptor(org.eclipse.persistence.descriptors.ClassDescriptor) HashMap(java.util.HashMap) EntityManagerImpl(org.eclipse.persistence.internal.jpa.EntityManagerImpl) FormerEmployment(org.eclipse.persistence.testing.models.jpa.composite.advanced.member_2.FormerEmployment) UnitOfWorkChangeSet(org.eclipse.persistence.sessions.changesets.UnitOfWorkChangeSet) ArrayList(java.util.ArrayList) Department(org.eclipse.persistence.testing.models.jpa.composite.advanced.member_1.Department) ObjectChangeSet(org.eclipse.persistence.internal.sessions.ObjectChangeSet) Vector(java.util.Vector) HashSet(java.util.HashSet) EmploymentPeriod(org.eclipse.persistence.testing.models.jpa.composite.advanced.member_2.EmploymentPeriod) ObjectChangeSet(org.eclipse.persistence.internal.sessions.ObjectChangeSet) DatabaseMapping(org.eclipse.persistence.mappings.DatabaseMapping) LargeProject(org.eclipse.persistence.testing.models.jpa.composite.advanced.member_3.LargeProject) SuperLargeProject(org.eclipse.persistence.testing.models.jpa.composite.advanced.member_3.SuperLargeProject) Project(org.eclipse.persistence.testing.models.jpa.composite.advanced.member_3.Project) SmallProject(org.eclipse.persistence.testing.models.jpa.composite.advanced.member_3.SmallProject) EntityManager(jakarta.persistence.EntityManager) JpaEntityManager(org.eclipse.persistence.jpa.JpaEntityManager) Employee(org.eclipse.persistence.testing.models.jpa.composite.advanced.member_2.Employee) Equipment(org.eclipse.persistence.testing.models.jpa.composite.advanced.member_3.Equipment) DatabaseSessionImpl(org.eclipse.persistence.internal.sessions.DatabaseSessionImpl) CopyGroup(org.eclipse.persistence.sessions.CopyGroup) PhoneNumber(org.eclipse.persistence.testing.models.jpa.composite.advanced.member_3.PhoneNumber) Map(java.util.Map) HashMap(java.util.HashMap) ChangeRecord(org.eclipse.persistence.sessions.changesets.ChangeRecord) LargeProject(org.eclipse.persistence.testing.models.jpa.composite.advanced.member_3.LargeProject) SuperLargeProject(org.eclipse.persistence.testing.models.jpa.composite.advanced.member_3.SuperLargeProject)

Example 8 with CopyGroup

use of org.eclipse.persistence.sessions.CopyGroup in project eclipselink by eclipse-ee4j.

the class EntityManagerJUnitTestSuite method internalTestChangeRecordKeepOldValue.

public void internalTestChangeRecordKeepOldValue(boolean addSecondStep) {
    if (isOnServer()) {
        // the test relies upon keeping attached objects between transactions.
        return;
    }
    // but these are transient for remote sessions.
    if (getDatabaseSession().isRemoteSession()) {
        return;
    }
    AbstractSession session = getDatabaseSession();
    ChangeRecordKeepOldValueListener listener = new ChangeRecordKeepOldValueListener();
    session.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);
        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();
        session.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 = session.getDescriptor(original);
            if (!descriptor.isAggregateDescriptor()) {
                Object backup = entry.getValue();
                if (original == backup) {
                    fail("Test problem: backup failed: original == backup: " + original);
                }
                if (!session.compareObjects(original, backup)) {
                    fail("Test problem: backup failed: compareObjects(original, backup) == false: " + original + "; " + backup);
                }
            }
        }
        Set deleted = new HashSet();
        // 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));
        // **temp for debug
        FormerEmployment fe = emp.getFormerEmployment();
        // 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);
        deleted.add(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);
        deleted.add(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);
        deleted.add(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.
        // **temp for debug
        FormerEmployment fe2 = null;
        if (addSecondStep) {
            // Aggregate
            emp.setPeriod(new EmploymentPeriod());
            emp.getPeriod().setStartDate(Helper.dateFromYearMonthDate(2001, 0, 1));
            emp.getPeriod().setEndDate(Helper.dateFromYearMonthDate(2003, 0, 1));
            // Aggregate
            // **temp for debug
            fe2 = emp.getFormerEmployment();
            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));*/
            // 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);
            deleted.add(emp1New);
            deleted.add(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);
            deleted.add(proj1New);
            deleted.add(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);
            deleted.add(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 this 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);
            deleted.add(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();
        session.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<Map.Entry<Object, org.eclipse.persistence.internal.sessions.ObjectChangeSet>> itChangeSets = ((org.eclipse.persistence.internal.sessions.UnitOfWorkChangeSet) listener.uowChangeSet).getCloneToObjectChangeSet().entrySet().iterator();
        while (itChangeSets.hasNext()) {
            Map.Entry<Object, org.eclipse.persistence.internal.sessions.ObjectChangeSet> entry = itChangeSets.next();
            Object object = entry.getKey();
            ClassDescriptor descriptor = session.getDescriptor(object);
            if (!descriptor.isAggregateDescriptor()) {
                ObjectChangeSet changeSet = entry.getValue();
                if (!(deleted.contains(object)) && !changeSet.isNew()) {
                    List<ChangeRecord> changes = changeSet.getChanges();
                    if (changes != null && !changes.isEmpty()) {
                        Object oldValueObject = oldValueMap.get(object);
                        if (oldValueObject != null) {
                            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<Object, org.eclipse.persistence.internal.sessions.ObjectChangeSet> entry = itChangeSets.next();
            Object object = entry.getKey();
            ClassDescriptor descriptor = session.getDescriptor(object);
            if (!descriptor.isAggregateDescriptor()) {
                ObjectChangeSet changeSet = entry.getValue();
                if (!(deleted.contains(object)) && !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 ((oldValueObject != null) && !session.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 = session.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);
        // 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 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 (!session.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(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);
        session.getEventManager().removeListener(listener);
    }
}
Also used : SmallProject(org.eclipse.persistence.testing.models.jpa.fieldaccess.advanced.SmallProject) UnitOfWork(org.eclipse.persistence.sessions.UnitOfWork) Set(java.util.Set) ObjectChangeSet(org.eclipse.persistence.sessions.changesets.ObjectChangeSet) HashSet(java.util.HashSet) UnitOfWorkChangeSet(org.eclipse.persistence.sessions.changesets.UnitOfWorkChangeSet) Address(org.eclipse.persistence.testing.models.jpa.fieldaccess.advanced.Address) ClassDescriptor(org.eclipse.persistence.descriptors.ClassDescriptor) HashMap(java.util.HashMap) EntityManagerImpl(org.eclipse.persistence.internal.jpa.EntityManagerImpl) FormerEmployment(org.eclipse.persistence.testing.models.jpa.fieldaccess.advanced.FormerEmployment) UnitOfWorkChangeSet(org.eclipse.persistence.sessions.changesets.UnitOfWorkChangeSet) ArrayList(java.util.ArrayList) Department(org.eclipse.persistence.testing.models.jpa.fieldaccess.advanced.Department) SessionLogEntry(org.eclipse.persistence.logging.SessionLogEntry) Vector(java.util.Vector) AbstractSession(org.eclipse.persistence.internal.sessions.AbstractSession) HashSet(java.util.HashSet) EmploymentPeriod(org.eclipse.persistence.testing.models.jpa.fieldaccess.advanced.EmploymentPeriod) ObjectChangeSet(org.eclipse.persistence.sessions.changesets.ObjectChangeSet) DatabaseMapping(org.eclipse.persistence.mappings.DatabaseMapping) LargeProject(org.eclipse.persistence.testing.models.jpa.fieldaccess.advanced.LargeProject) SuperLargeProject(org.eclipse.persistence.testing.models.jpa.fieldaccess.advanced.SuperLargeProject) SmallProject(org.eclipse.persistence.testing.models.jpa.fieldaccess.advanced.SmallProject) Project(org.eclipse.persistence.testing.models.jpa.fieldaccess.advanced.Project) EntityManager(jakarta.persistence.EntityManager) JpaEntityManager(org.eclipse.persistence.jpa.JpaEntityManager) Employee(org.eclipse.persistence.testing.models.jpa.fieldaccess.advanced.Employee) Equipment(org.eclipse.persistence.testing.models.jpa.fieldaccess.advanced.Equipment) CopyGroup(org.eclipse.persistence.sessions.CopyGroup) PhoneNumber(org.eclipse.persistence.testing.models.jpa.fieldaccess.advanced.PhoneNumber) Map(java.util.Map) NoIdentityMap(org.eclipse.persistence.testing.models.jpa.fieldaccess.advanced.NoIdentityMap) HashMap(java.util.HashMap) ChangeRecord(org.eclipse.persistence.sessions.changesets.ChangeRecord) LargeProject(org.eclipse.persistence.testing.models.jpa.fieldaccess.advanced.LargeProject) SuperLargeProject(org.eclipse.persistence.testing.models.jpa.fieldaccess.advanced.SuperLargeProject)

Example 9 with CopyGroup

use of org.eclipse.persistence.sessions.CopyGroup in project eclipselink by eclipse-ee4j.

the class SimpleSerializeFetchGroupTests method copyGroupMerge2.

public void copyGroupMerge2() {
    // Search for an Employee with an Address and Phone Numbers
    EntityManager em = createEntityManager();
    try {
        beginTransaction(em);
        TypedQuery<Employee> query = em.createQuery("SELECT e FROM Employee e", Employee.class);
        query.setHint(QueryHints.BATCH, "e.address");
        List<Employee> employees = query.getResultList();
        assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
        System.out.println(">>> Employees retrieved");
        // Copy only its names and phone Numbers
        AttributeGroup group = new CopyGroup();
        group.addAttribute("firstName");
        group.addAttribute("lastName");
        group.addAttribute("address");
        List<Employee> employeesCopy = (List<Employee>) em.unwrap(JpaEntityManager.class).copy(employees, group);
        assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
        System.out.println(">>> Employees copied");
        for (Employee empCopy : employeesCopy) {
            // Modify the detached Employee inverting the names, adding a phone number, and setting the salary
            String firstName = empCopy.getFirstName();
            String lastName = empCopy.getLastName();
            empCopy.setFirstName(lastName);
            empCopy.setLastName(firstName);
            // Note that salary was not part of the original FetchGroup
            // empCopy.setSalary(1);
            // Merge the detached employee
            em.merge(empCopy);
        }
        System.out.println(">>> Sparse merge complete");
        // Flush the changes to the database
        em.flush();
        System.out.println(">>> Flush complete");
    } finally {
        rollbackTransaction(em);
        closeEntityManager(em);
    }
}
Also used : EntityManager(jakarta.persistence.EntityManager) JpaEntityManager(org.eclipse.persistence.jpa.JpaEntityManager) Employee(org.eclipse.persistence.testing.models.jpa.advanced.Employee) CopyGroup(org.eclipse.persistence.sessions.CopyGroup) AttributeGroup(org.eclipse.persistence.queries.AttributeGroup) ArrayList(java.util.ArrayList) List(java.util.List) IndirectList(org.eclipse.persistence.indirection.IndirectList)

Example 10 with CopyGroup

use of org.eclipse.persistence.sessions.CopyGroup in project eclipselink by eclipse-ee4j.

the class SimpleSerializeFetchGroupTests method copyGroupMerge.

public void copyGroupMerge() {
    // Search for an Employee with an Address and Phone Numbers
    EntityManager em = createEntityManager();
    try {
        beginTransaction(em);
        TypedQuery<Employee> query = em.createQuery("SELECT e FROM Employee e WHERE e.id IN (SELECT MIN(ee.id) FROM Employee ee)", Employee.class);
        Employee emp = query.getSingleResult();
        assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
        System.out.println(">>> Employee retrieved");
        // Copy only its names and phone Numbers
        AttributeGroup group = new CopyGroup();
        group.addAttribute("firstName");
        group.addAttribute("lastName");
        group.addAttribute("address");
        Employee empCopy = (Employee) em.unwrap(JpaEntityManager.class).copy(emp, group);
        assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
        System.out.println(">>> Employee copied");
        // Modify the detached Employee inverting the names, adding a phone number, and setting the salary
        empCopy.setFirstName(emp.getLastName());
        empCopy.setLastName(emp.getFirstName());
        // Note that salary was not part of the original FetchGroup
        // empCopy.setSalary(1);
        // Merge the detached employee
        em.merge(empCopy);
        System.out.println(">>> Sparse merge complete");
        // Flush the changes to the database
        em.flush();
        System.out.println(">>> Flush complete");
    } finally {
        rollbackTransaction(em);
        closeEntityManager(em);
    }
}
Also used : EntityManager(jakarta.persistence.EntityManager) JpaEntityManager(org.eclipse.persistence.jpa.JpaEntityManager) Employee(org.eclipse.persistence.testing.models.jpa.advanced.Employee) CopyGroup(org.eclipse.persistence.sessions.CopyGroup) AttributeGroup(org.eclipse.persistence.queries.AttributeGroup)

Aggregations

CopyGroup (org.eclipse.persistence.sessions.CopyGroup)24 EntityManager (jakarta.persistence.EntityManager)20 JpaEntityManager (org.eclipse.persistence.jpa.JpaEntityManager)18 ArrayList (java.util.ArrayList)8 HashSet (java.util.HashSet)8 Set (java.util.Set)7 Employee (org.eclipse.persistence.testing.models.jpa.advanced.Employee)7 UnitOfWorkChangeSet (org.eclipse.persistence.sessions.changesets.UnitOfWorkChangeSet)6 Employee (org.eclipse.persistence.testing.models.jpa.fieldaccess.advanced.Employee)6 ClassDescriptor (org.eclipse.persistence.descriptors.ClassDescriptor)5 ObjectChangeSet (org.eclipse.persistence.internal.sessions.ObjectChangeSet)5 Map (java.util.Map)4 DatabaseMapping (org.eclipse.persistence.mappings.DatabaseMapping)4 AttributeGroup (org.eclipse.persistence.queries.AttributeGroup)4 ResultSet (java.sql.ResultSet)3 HashMap (java.util.HashMap)3 List (java.util.List)3 Vector (java.util.Vector)3 IdentityHashSet (org.eclipse.persistence.internal.helper.IdentityHashSet)3 EntityManagerImpl (org.eclipse.persistence.internal.jpa.EntityManagerImpl)3