Part E: Repair that Fails due to Duplicate Entry

If you run the erroneous repair from Exercise Six, Part A, it will prevent the automatic dictionary from being updated when a member’s key is changed. If you change the key property of the member to be the same as that of another member, dictionary maintenance will not occur. You can then run a repair that resets the reference Product::myCompany.

The end state is then one in which the member is stored at an incorrect key. However, this is different from Part D, as there is the additional fact that the key property value is the same as that of another member so attempting to insert the member at its key property value will cause a duplicate key exception and the rebuild action will be aborted. In contrast to Part D, the second fix generated will run as a consequence of the first fix not being implemented.

  1. Ensure that existing errors have been corrected.

  2. Run the erroneous repair created in Part A.

  3. Run the following Workspace script to alter the key property values of the first instance of Product.

    beginTransaction;
        Product.firstInstance.productDescription :=
            Product.lastInstance.productDescription;
    commitTransaction;
  4. Obtain the fix to reset the Product::myCompany by running the following script.

    vars
        fixLine : String;
    begin
        fixLine := "FIX1: set " & Product.firstInstance.getOidString
                   & " myCompany " & Company.firstInstance.getOidString;
        write fixLine;
    end;

    The form of the fix should be as follows.

    FIX1: set 2975.1 myCompany 2973.1
  5. Run the repair constructed from the output of the previous step.

  6. Verify in the Object Inspector that both Product instances now have the same name and that the reference to the parent company is set.

  7. Run the Logical Certifier in analysis mode.

    Save the output in a new folder named according to the update mode for the inverse.

  8. Run the repair.

    Observe that the rebuild fix to address the invalid key fails due to a duplicate key being encountered. This is documented in the repair error log, as follows.

    Error: FIX1 rebuild AllProductsByDescription/2976.1.2973.2.1: size before=2, size after=2 results in duplicate

    The end state of the system will be determined by the second fix, which in turn depends on the update mode in place. At this point, you would typically evaluate the situation and determine that the two errors reported in the analysis phase come from the same condition (an object at the wrong key). You may be able to determine that the key property value is incorrect (as is the case here) and the correct value from other information (the product price, in this example).

    You would then set the correct key property value (for example, by a JadeScript) and then go ahead with the rebuild, if required.

  9. Verify that the second error reported (and corresponding fix) will vary, according to the update mode (Company <‑> Product), as follows.

    • Collection is automatically updated. (Both fixes will fail.)

      ‑‑‑‑ Errors for LogCertTester::Product ‑‑‑‑‑‑‑‑‑‑‑‑‑‑
      *** Error 1: Collection does not include reference to inverse object
          Company/2973.1‑>Company::allMyProducts (inverse of Product/2975.1‑>Product::myCompany) does not include Product/2975.1 (error coll=AllProductsByDescription/2976.1.2973.2.1)
      FIX2: add 2976.1.2973.2.1 2975.1  CHECK: '2975.1'.asOid.getPropertyValue('myCompany').Object='2973.1'.asOid and not '2973.1'.asOid.getPropertyValue('allMyProducts').Object.Collection.includes('2975.1'.asOid)
    • Reference Product::myCompany is automatically updated. (Removes part of the relationship.)

      ‑‑‑‑ Errors for LogCertTester::Product ‑‑‑‑‑‑‑‑‑‑‑‑‑‑
      *** Error 8: No inverses found for Product/2975.1‑>Product::myCompany (obj=Product/2975.1, related=Company/2973.1) (2975.1 created 22 September 2009, 11:32:51)
      FIX2: null 2975.1 myCompany  CHECK: '2975.1'.asOid.getPropertyValue('myCompany').Object='2973.1'.asOid
    • Both sides man/auto. (No outcome unless a choice is made. Choices match first two cases.)

      ‑‑‑‑ Errors for LogCertTester::Product ‑‑‑‑‑‑‑‑‑‑‑‑‑‑
      *** Error 8: No inverses found for Product/2975.1‑>Product::myCompany (obj=Product/2975.1, related=Company/2973.1) (2975.1 created 22 September 2009, 11:32:51)
      //FIX2: Choose either first fix if man/auto Product::myCompany acts as auto else following 1 line(s)
      //FIX2: null 2975.1 myCompany  CHECK: '2975.1'.asOid.getPropertyValue('myCompany').Object='2973.1'.asOid
      //FIX2: add 2976.1.2973.2.1 2975.1  CHECK: '2975.1'.asOid.getPropertyValue('myCompany').Object='2973.1'.asOid and not '2973.1'.asOid.getPropertyValue('allMyProducts').Object.Collection.includes('2975.1'.asOid)