Uploaded image for project: 'Cayenne'
  1. Cayenne
  2. CAY-1725

NullPointerException from call to removeToManyTarget

    XMLWordPrintableJSON

Details

    • Bug
    • Status: Closed
    • Major
    • Resolution: Fixed
    • 3.0.1, 3.0.2
    • 3.1B2, 3.2.M1, 3.0.3
    • Core Library
    • None

    Description

      I am using Cayenne version 3.0.1.

      In CayenneModeler I have created an "Approver" DbEntity and a "Department" DbEntity (as well as the corresponding ObjEntity classes). I have also created an "Authorization" DbEntity to act as a join table for the Approver and Department tables. Every Approver object has a list of Department objects associated with it, and vice versa so in CayenneModeler I have added a "departmentArray" relationship to the Approver object which has "to many, list" semantics.

      When I use the Approver method "void addToDepartmentArray (Department)" everything works fine, but when I use the Approver method "void removeFromDepartmentArray (Department)" (which simple calls removeToManyTarget) a NullPointerException is thrown. A backtrace and quick debug tells me the null pointer exception originates from:

      org.apache.cayenne.access.DataDomainFlattenedBucket.addFlattenedDelete(DataDomainFlattenedBucket.java:82)

      The code on lines 81 and 82 of this file are as follows:

      [81] List flattenedSnapshots = flattenedDeleteInfo.buildJoinSnapshotsForDelete(node);
      [82] if (!flattenedSnapshots.isEmpty()) {

      Inspecting flattenedSnapshots on line 82 shows that flattenedSnapshots is null hence accessing the isEmpty method is causing the null pointer exception.

      I have also tested with Cayenne 3.0.2 and the same error occurs.

      Here is a simple code snippet to reproduce this error:

      // make sure our context is clear of any changes
      context.rollbackChanges ();

      // set up a new approver and department
      Approver approver = context.newObject (Approver.class);
      Department dept = context.newObject (Department.class);

      approver.setLogin ("approver");
      dept.setName ("departmentA");

      // add the department to the approver
      approver.addToDepartmentArray (dept);

      // commit these to the database, so far everything should be running fine
      context.commitChanges ();

      // remove the department from the approver...
      // this should work fine because we haven't committed yet
      approver.removeFromDepartmentArray (dept);

      try

      { // this is where things go bad context.commitChanges (); }

      catch (Exception e)

      { // error has occurred // at this point the record in the Authorization table still exists }

      Attachments

        1. cayenne.xml
          0.3 kB
          Aaron Andersen
        2. KeysDomainNode.driver.xml
          0.2 kB
          Aaron Andersen
        3. KeysMap.map.xml
          19 kB
          Aaron Andersen

        Issue Links

          Activity

            People

              Unassigned Unassigned
              aander73 Aaron Andersen
              Votes:
              0 Vote for this issue
              Watchers:
              2 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved: