public static TestSuite getComplexUpdateObjectTestSuite() {
    TestSuite suite = new TestSuite();
    suite.setName("EmployeeComplexUpdateTestSuite");
    suite.setDescription(
        "This suite tests the updating of each an employee by adding and/or removing managed employees and/or phones.");

    Class employeeClass = Employee.class;
    PopulationManager manager = PopulationManager.getDefaultManager();
    Employee originalEmployee = (Employee) manager.getObject(employeeClass, "0001");
    Employee otherEmployee = (Employee) manager.getObject(employeeClass, "0002");

    // add a managed Employee from other Employee managed List; remove the first managed Employee.
    suite.addTest(
        new EmployeeComplexUpdateTest(
            originalEmployee,
            otherEmployee.getManagedEmployees().get(0),
            originalEmployee.getManagedEmployees().get(0)));
    // remove the first Phone.
    suite.addTest(
        new EmployeeComplexUpdateTest(
            originalEmployee, (Object) null, originalEmployee.getPhoneNumbers().get(0)));
    // add a managed Employee from other Employee managed List and new phone;
    // remove the first two managed Employees and the first Phone.
    Employee newEmployee = new Employee();
    newEmployee.setFirstName("New");
    PhoneNumber newPhoneNumber = new PhoneNumber("home", "001", "0000001");
    suite.addTest(
        new EmployeeComplexUpdateTest(
            originalEmployee,
            new Object[] {otherEmployee.getManagedEmployees().get(0), newEmployee, newPhoneNumber},
            new Object[] {
              originalEmployee.getManagedEmployees().get(0),
              originalEmployee.getManagedEmployees().get(1),
              originalEmployee.getPhoneNumbers().get(0)
            }));
    suite.addTest(new CascadeLockingTest());
    suite.addTest(new TargetLockingTest_AddRemoveTarget());

    return suite;
  }
 public void test() {
   UnitOfWork uow = getSession().acquireUnitOfWork();
   Employee managerClone = (Employee) uow.registerObject(employee[0]);
   // remove all managed Employees (1 and 2)
   managerClone.getManagedEmployees().clear();
   // add to managed list new Employees (3 and 4)
   Employee employee3Clone = (Employee) uow.registerObject(employee[3]);
   Employee employee4Clone = (Employee) uow.registerObject(employee[4]);
   managerClone.addManagedEmployee(employee3Clone);
   managerClone.addManagedEmployee(employee4Clone);
   // after commit the  versions of all Employees should be changed.
   uow.commit();
 }
    public void test() {
      // clear cache
      getSession().getIdentityMapAccessor().initializeAllIdentityMaps();
      // create batch read query, set its selectionCriteria
      ReadAllQuery query = new ReadAllQuery(Employee.class);
      setSelectionCriteria(query);
      // before adding batch read attributes clone the query to create control query
      ReadAllQuery controlQuery = (ReadAllQuery) query.clone();
      // add batch read attributes
      Expression managedEmployees = query.getExpressionBuilder().get("managedEmployees");
      Expression managedEmployeesPhoneNumbers = managedEmployees.get("phoneNumbers");
      query.addBatchReadAttribute(managedEmployeesPhoneNumbers);
      // execute the query
      List employees = (List) getSession().executeQuery(query);
      if (employees.isEmpty()) {
        throw new TestProblemException("No Employees were read");
      }
      // need to instantiate only a single Phone on a single managed Employee to trigger sql that
      // reads data from the db for all.
      // still need to trigger all the indirections - but (except the first one) they are not
      // accessing the db
      // (the data is already cached in the value holders).
      printDebug("Trigger batch reading results");
      boolean isConnected = true;
      for (int i = 0; i < employees.size(); i++) {
        Employee manager = (Employee) employees.get(i);
        if (!manager.getManagedEmployees().isEmpty()) {
          printDebug("Manager = " + manager);
          for (int j = 0; j < manager.getManagedEmployees().size(); j++) {
            Employee emp = (Employee) manager.getManagedEmployees().get(j);
            printDebug("     " + emp);
            for (int k = 0; k < emp.getPhoneNumbers().size(); k++) {
              if (isConnected) {
                // need to instantiate only a single Phone on a single managed Employee to trigger
                // sql that reads data from the db for all.
                // to ensure that no other sql is issued close connection.
                ((AbstractSession) getSession()).getAccessor().closeConnection();
                isConnected = false;
              }
              PhoneNumber phone = (PhoneNumber) emp.getPhoneNumbers().get(k);
              printDebug("          " + phone);
            }
          }
        } else {
          printDebug(manager.toString());
        }
      }
      if (!isConnected) {
        // reconnect connection
        ((AbstractSession) getSession())
            .getAccessor()
            .reestablishConnection((AbstractSession) getSession());
      }
      printDebug("");

      // obtain control results
      // clear cache
      getSession().getIdentityMapAccessor().initializeAllIdentityMaps();
      // execute control query
      List controlEmployees = (List) getSession().executeQuery(controlQuery);
      // instantiate all value holders that the batch query expected to instantiate
      printDebug("Trigger control results");
      for (int i = 0; i < controlEmployees.size(); i++) {
        Employee manager = (Employee) controlEmployees.get(i);
        if (!manager.getManagedEmployees().isEmpty()) {
          printDebug("Manager = " + manager);
          for (int j = 0; j < manager.getManagedEmployees().size(); j++) {
            Employee emp = (Employee) manager.getManagedEmployees().get(j);
            printDebug("     " + emp);
            for (int k = 0; k < emp.getPhoneNumbers().size(); k++) {
              PhoneNumber phone = (PhoneNumber) emp.getPhoneNumbers().get(k);
              printDebug("          " + phone);
            }
          }
        } else {
          printDebug(manager.toString());
        }
      }

      // compare results
      String errorMsg =
          JoinedAttributeTestHelper.compareCollections(
              employees,
              controlEmployees,
              getSession().getClassDescriptor(Employee.class),
              ((AbstractSession) getSession()));
      if (errorMsg.length() > 0) {
        throw new TestErrorException(errorMsg);
      }
    }
 public EmployeeComplexUpdateTest(
     Employee originalEmployee, Object[] objectsToAdd, Object[] objectsToRemove) {
   super(originalEmployee);
   this.usesUnitOfWork = true;
   if (objectsToAdd != null) {
     for (int i = 0; i < objectsToAdd.length; i++) {
       Object objectToAdd = objectsToAdd[i];
       if (objectToAdd instanceof Employee) {
         if (!originalEmployee.getManagedEmployees().contains(objectToAdd)) {
           managedEmployeesToAdd.add((Employee) objectToAdd);
         } else {
           throw new TestWarningException(
               "OriginalEmployee: "
                   + originalEmployee
                   + " already manages employee to be added: "
                   + objectToAdd);
         }
       } else {
         // must be Phone
         if (!originalEmployee.getPhoneNumbers().contains(objectToAdd)) {
           phonesToAdd.add((PhoneNumber) objectToAdd);
         } else {
           throw new TestWarningException(
               "OriginalEmployee: "
                   + originalEmployee
                   + " already has the phonee to be added: "
                   + objectToAdd);
         }
       }
     }
   }
   if (objectsToRemove != null) {
     for (int i = 0; i < objectsToRemove.length; i++) {
       Object objectToRemove = objectsToRemove[i];
       if (objectToRemove instanceof Employee) {
         if (originalEmployee.getManagedEmployees().contains(objectToRemove)) {
           managedEmployeesToRemove.add((Employee) objectToRemove);
         } else {
           throw new TestWarningException(
               "OriginalEmployee: "
                   + originalEmployee
                   + " doesn't manage employee to be removed: "
                   + objectToRemove);
         }
       } else {
         // must be Phone
         if (originalEmployee.getPhoneNumbers().contains(objectToRemove)) {
           phonesToRemove.add((PhoneNumber) objectToRemove);
         } else {
           throw new TestWarningException(
               "OriginalEmployee: "
                   + originalEmployee
                   + " doesn't have the phonee to be removed: "
                   + objectToRemove);
         }
       }
     }
   }
   // generate a meaningful test name
   String employeeString = "";
   if (managedEmployeesToAdd.size() > 0 || managedEmployeesToRemove.size() > 0) {
     String addString = "";
     if (managedEmployeesToAdd.size() > 0) {
       addString = "add " + managedEmployeesToAdd.size();
     }
     String removeString = "";
     if (managedEmployeesToRemove.size() > 0) {
       removeString = "remove " + managedEmployeesToRemove.size();
     }
     employeeString =
         addString
             + (addString.length() > 0 && removeString.length() > 0 ? " and " : " ")
             + removeString
             + " Employees";
   }
   String phoneString = "";
   if (phonesToAdd.size() > 0 || phonesToRemove.size() > 0) {
     String addString = "";
     if (phonesToAdd.size() > 0) {
       addString = "add " + phonesToAdd.size();
     }
     String removeString = "";
     if (phonesToRemove.size() > 0) {
       removeString = "remove " + phonesToRemove.size();
     }
     phoneString =
         addString
             + (addString.length() > 0 && removeString.length() > 0 ? " and " : "")
             + removeString
             + " Phones";
   }
   setName(
       "EmployeeComplexUpdateTest: "
           + employeeString
           + (employeeString.length() > 0 && phoneString.length() > 0 ? "; " : "")
           + phoneString
           + ";");
   setDescription(
       "The test updates original Employee object: "
           + originalObject.toString()
           + " from the database by adding and/or removing managedEmployees and/or PhoneNumbers and verifies that the object updated correctly.");
 }