11 Replies Latest reply: Apr 4, 2006 2:46 PM by 475070 RSS

    LOV not returning value into detail record with multiple parents (UIX only)

    459321
      JHeadstart version: 10.1.2.0 (build 19) and probably 10.1.2.1
      ADF UIX version: 2.2.16
      JDeveloper version: 10.1.2.17.84

      Description
      After launching a LOV and selecting a value from it, the lookup values are not displayed in the base record. This holds true only for UIX and works fine in JSP.

      Steps
      1. Take three tables (EOs): A, B, and C; where A and B are both parents of C (for example an intersection table).
      2. Add lookup attributes from A to the VO of C (according to section Generating List of Values in chap 3 of JHeadstart 10g for ADF Developer’s Guide).
      3. Next, define a simple ADF BC application module involving a single view B and a master-detail relationship between A and C.
      4. Also adjust the JHS structure file (also according to the Dev Guide), in order to define the LOV on the lookup display attribute and to hide the non-meaningful key from the UI.
      5. Generate UIX and run.
      6. Navigate to details and insert new row, launch LOV, select value, LOV disappears and values are not displayed in detail record.

      This looks like a bug because when the view-controller tier is generated in JSP, the LOV works great. I have created and uploaded a reproducable case based on the HR schema. This involves employee detail object that has a job (parent1) and a department (parent2) . The test case can be downloaded here: http://technology.amis.nl/blog/wp-content/images/repro2.zip .
      Note that the issue described above does not occur in case of a single master-detail relationship. A test case that consists of a location detail object that has a country parent object, worked fine as regards to this LOV issue (both in JSP and UIX).
        • 1. Re: LOV not returning value into detail record with multiple parents (UIX o
          441337
          Erik and I are colleagues and Erik asked me to verify this behaviour with JHeadstart 10.1.2.1. I used his zip file for the ADF BC part and created a new view project. Next I enabled JHeadstart on this project and generated a new Application Structure file. While creating this ASF, I selected to generate LOVs for all lookups.
          Then I modified nothing, simply generated the application and started it. Selecting "EmployeesHavingJob" and trying to assign a Department to a new row proved that here, too, no value returned from the LOV was entered in the field for the Department.
          FYI, I have set the Java options

          -Djbo.debugoutput=console -Djbo.logging.show.function=true

          to the Runner settings of both the model and view projects. Upon selecting a value from the LOV and clicking the Select button, I see the correct Department is selected. Next, I see the selected Department ID to be assigned to an existing row. I selected the IT department and this shows up in the OC4J log:

          <EmployeesRow PS="0">
          <JobId>AD_PRES</JobId>
          <DepartmentId>60</DepartmentId>
          </EmployeesRow>

          This is the row for employee with name "Steven King" who actually is in Department with ID 90, which is the EXECUTIVE department. A little while later in the log, I see the Department ID to be assigned to a job with no ID:

          <EmployeesRow PS="0">
          <JobId></JobId>
          <DepartmentId>60</DepartmentId>
          </EmployeesRow>

          And then the application just seems to wait for ever. The status bar in Internet Explorer keeps on indicating it's waiting for more data to be returned from the webserver while the OC4J log does nothing anymore.

          I have this same problem in an application I am working on for a customer using JHeadstart 10.1.2.1, so would you please look into this and provide a fix if possible?


          Thanks in advance,

          Wouter van Reeven
          AMIS
          • 2. Re: LOV not returning value into detail record with multiple parents (UIX o
            441337
            By the way, I use JDeveloper 10.1.2 build 1913.
            • 3. Re: LOV not returning value into detail record with multiple parents (UIX o
              Steven Davelaar-Oracle
              Wouter, Erik,

              I was able to reproduce your problem. So far I found out it is probably related to the Composite Association checkbox of the EO association. When I check this checkbox in the EmpJobFkAssoc, the lov values are displayed correctly, however, then error oracle.jbo.InvalidOwnerException: JBO-25030: Failed to find or invalidate owning entity.
              is displayed. Which is strange as well because this error should only occur if multiple associations with the same parent have the composite association checkbox checked. Which is not the case. Anyway, I will further investigate and keep you posted.

              Thanks for the testcase!

              Steven Davelaar,
              JHeadstart Team.
              • 4. Re: LOV not returning value into detail record with multiple parents (UIX o
                Steven Davelaar-Oracle
                Wouter, Erik,

                I found out the cause of the problem. What happens is the following:

                - In JhsDataAction.onLovSelect, JHeadstart creates a new row in the detail iterator, and sets the selected LOV value on the appropriate attribute. Since it is a detail iterator, ADF BC will automatically populate the foreign key attribute to the parent VO with the key attribute of the parent, which is JobId in your testcase.

                - After returning from the LOV, the PPR action on the base page is executed, which results in execution of EmployeeHavingJob.do. In this action, as part of processMultiRowUpdate, any other values that might have been filled in by the user in the same row, prior to invoking the LOV, are applied to the row created in onLovSelect.

                - In your testcase, the parent referencing attribute JobId is included in the table, so JobId is updated and set to null again, which effectively removes the just created row from the detail iterator, and that's why you do not see the newly created row with the selected value ...

                Conclusion: do not include the parent-referencing attribute in a detail table (makes no sense anyway), or make it read only. In general, apart from this LOV issue, if the user would modify this attribute and save the changes, the updated row would disappear, which is rather confusing to the user.

                Steven Davelaar,
                JHeadstart Team.
                • 5. Re: LOV not returning value into detail record with multiple parents (UIX o
                  441337
                  Hi Steven,


                  Many thanks for providing this solution. I was able to verify that not showing the DepartmentID in the Employees table solves this issue. By the way, I only tested with Display set to "false". I didn't try hidden, but I assume that would lead to the same problem since it then still is included in the UIX page and it will get a value when onLovSelect is performed. In the project I am working on I also am able to verify that this solution works fine.
                  Perhaps your team could consider adding this to the JHeadstart Developer's Guide? Initializing JHeadstart on a project and generating a first view ususally means checking if all the fancy details, like LOVs, work and then paying attention to the look and feel of the pages. It's very easy to encounter this issue when using the default settings that initializing JHeadstart sets for you.

                  Anyway, thanks for the help once again!


                  Greets, Wouter
                  • 6. Re: LOV not returning value into detail record with multiple parents (UIX o
                    Steven Davelaar-Oracle
                    Wouter, we have added this to the release notes of the upcoming patch.

                    Steven Davelaar,
                    JHeadstart Team.
                    • 7. Re: LOV not returning value into detail record with multiple parents (UIX o
                      459321
                      Hi Steven,

                      I followed your instructions but I have still some question marks regarding what is exactly happening.

                      1. I made the foreign key jobId read-only (by setting its Updateable view attribute to Never). This didn't solve the issue. This results in a record with attributes filled in, including jobId, but without the lookup attributes.

                      2. Then I set the custom property Display to false. This didn't do the trick either. However according to your explanation about processMultiRowUpdate, I would expect that this would be sufficient, because jobId is removed now from the list of attributes that might have been filled in by the user prior to invoking the LOV.

                      3. Now I set the foreign key to the lookup entity, namely departmentId to custom property Dispay Hidden. At compile time JHeadstart issues the warning:
                      JBC-00027 - EmployeesView.DepartmentId: Changing Custom Property Display from hidden to false to ensure proper LOV behavior

                      I understand now that also the foreign key value prior to the LOV invocation is re-set in the detail iterator.

                      Both keys must have a display property set to false because when (1) the jobId is displayed we loose the parent record and the detail becomes a kind of zomby, and when (2) the departmentId is displayed we loose the lookup data. I agree that it makes no sense to show the technical keys, but in the last instance the wish to show these keys is basically a functional question... and the customer is the king. The jobId can still be made visible as long as it is read-only but then still there might be a weird customer who wants to have the possibility to change the parent (in this example the job of an employee).

                      My conclusion is that I am very happy that I have a solution and also in a very short time (!!!), but there is still something that bothers me here... I am under the impression that there is first a JHeadstart Action and then an ADF action. The first one does some things like creating a new row in the detail iterator. But then the ADF action comes and does something with this iterator too, which results in resetting (clearing) of keys that were just set by the JHeadstart action. By saying that these fields shouldn't be displayed you shift the attention towards functional questions, but the solution should be technical. I can live with it, but still feel that there is something conflicting between the Jheadstart code and the standard, ADF code.

                      Kind Regards and many thanks for your fast service,

                      Erik
                      • 8. Re: LOV not returning value into detail record with multiple parents (UIX o
                        Steven Davelaar-Oracle
                        Erik,

                        This issue only applies in a table layout. The code to handle table updates is entirely JHeadstart code, so there is not a conflict between JHeadstart and ADF code, as no ADF code is involved. We could improve the multi row update code to ignore the parent-referencing attribute, just after an LOV has been used, but that is far from trivial, and requires complex coding for a situation that really should not occur, because the item should not be displayed as the row would simply disappear when the user changed the attribute.

                        Now, the second case, whether or not to display the DepartmentId is a different story. Nothing stops you from keeping the DepartmentId displayed as an input text. You will see that when you select a department in the LOV both the department name and id are copied back, provided that you specified the DepartmentId as base value attribute, and the DepartmentName as base display attribute.

                        Steven Davelaar,
                        JHeadstart Team.
                        • 9. Re: LOV not returning value into detail record with multiple parents (UIX o
                          475070
                          Steven,

                          I'm not sure if this is still an issue, but for us it's very important to be able to use the foreign-key as the display and value fields in LOVs in multiple-row tables. We have a legacy database that contains a lot of product catalogs, and in which the keys has special meanings and are known by the users. So they may type the key directly in the field or search in the LOV by description, but the value displayed should be the key itself.

                          Since this is very important to us, I've done a workaround which is very ugly but works:

                          1. In the writeLovValues (which appears to be the very last operation in lov selection), I put these lines:

                          String iterName = valueBinding.getIteratorBinding().getName();
                          Key key = currentRow.getKey();
                          daContext.getHttpServletRequest().getSession().setAttribute("lovRowKeys", key);
                          daContext.getHttpServletRequest().getSession().setAttribute("iterName", iterName);
                          daContext.getHttpServletRequest().getSession().setAttribute("valueBinding", valueBinding.getAttributeDef().getName());

                          They save the current row, the iterator name and the VO field which received the LOV field in session.

                          2. In the first lines of processMultiRowUpdateModel method, I put the following:

                          HttpServletRequest request = lcContext.getHttpServletRequest();

                          Row row[] = null;
                          Key key = null;
                          Object o = null;

                          String name = (String)request.getSession().getAttribute("iterName");

                          String valueBinding = null;
                          if (name != null && name.equals(tableBinding.getIteratorBinding().getName())) {
                          key = (Key)request.getSession().getAttribute("lovRowKeys");
                          valueBinding = (String)request.getSession().getAttribute("valueBinding");

                          request.getSession().removeAttribute("lovRowKeys");
                          request.getSession().removeAttribute("iterName");
                          request.getSession().removeAttribute("valueBinding");

                          row = tableBinding.getViewObject().findByKey(key, -1);

                          o = null;
                          if (row.length > 0) {
                          o = row[0].getAttribute(valueBinding);
                          }
                          }

                          They take saved attributes in session and hold the current field value that received the selected LOV value.

                          3. In the last lines of the processMultiRowUpdateModel:

                          if (name != null && name.equals(tableBinding.getIteratorBinding().getName())) {
                          if (row.length > 0 && o != null) {
                          row[0].setAttribute(valueBinding, o);
                          }
                          }

                          Which sets the value overwrote by the method, restoring the selected value in LOV.

                          It's very ugly but seens to work in all cases I've tested and I don't have the necessary time to design a true solution.

                          The question that remains is: I have 2 blank lines in a multi-row table. When I set a field by it's LOV window in the first blank row, a new row is added to the tabled with the selected value and I still have the last 2 blank lines. When I do the same with the last (not the first) blank row, it's not set in that line but in the first, and the 2 last lines remains blank. Is it the way Jhs is implemented or am I missing anything?

                          Thanks,

                          Eduardo
                          • 10. Re: LOV not returning value into detail record with multiple parents (UIX o
                            153666
                            Eduardo,

                            You asked:
                            The question that remains is: I have 2 blank lines in a multi-row table. When I set a field by it's LOV window in the first blank row, a new row is added to the tabled with the selected value and I still have the last 2 blank lines. When I do the same with the last (not the first) blank row, it's not set in that line but in the first, and the 2 last lines remains blank. Is it the way Jhs is implemented or am I missing anything?

                            The 2 blank lines in the table appear because you have set the newRows property of the group to 2. These empty lines do not represent rows in the View Object, they are artificially added to the rows displayed in UIX by the JHeadstart Runtime. See the JHeadstart Developer's Guide, chapter 5 JHeadstart Extensions to ADF Runtime, User Interface Widgets, Select List (dropdown), Wrapping the ADF Table Binding.

                            When you use the LOV to put in a value, the JHeadstart Runtime code (JhsDataAction.onLovSelect) creates a new row in the View Object. It is default behavior that this new row is then displayed immediately after the queried rows that also belong to the View Object, followed again by 2 new rows. This is because the ADF Table Binding now includes the new row, and the JHeadstart code wraps the table binding again and adds 2 empty rows.

                            Hope this explains it,
                            Sandra Muller
                            JHeadstart Team
                            Oracle Consulting
                            • 11. Re: LOV not returning value into detail record with multiple parents (UIX o
                              475070
                              Thanks Sandra, this is the kind of answer I was looking for.

                              Thanks a lot,

                              Eduardo