Kuali Rice Development
  1. Kuali Rice Development
  2. KULRICE-13088

ObjectUtils deep copy related methods need to be ported over to JPA

    Details

    • Type: Task Task
    • Status: Closed Closed
    • Priority: Critical Critical
    • Resolution: Fixed
    • Affects Version/s: 2.5
    • Fix Version/s: 2.5
    • Component/s: Development
    • Security Level: Public (Public: Anyone can view)
    • Labels:
      None
    • Similar issues:
      KULRICE-11302Need JPA implementations for some persistence related methods that the KNS used to use.
      KULRICE-13138Apply the new deep copy method to Rice objects
      KULRICE-11177Need JPA related caching functionality to improve performance and support clustering
      KULRICE-13149Address problems with JPA related caching
      KULRICE-4084Port Chitra's changes to KimRoleDaoOjb to the Jpa dao after merging the 1.0.2 branch changes into 1.1
      KULRICE-13994Copy maintenance function needs option to copy readOnly fields
      KULRICE-3892Find all references to OJB's ProxyHelper class and figure out how to create a JPA equivalent where needed
      KULRICE-10110Cleanup on copy methods
      KULRICE-3888ActionListTest.testActionListCount() needs refactoring to comply with the OJB-to-JPA conversion
      KULRICE-4381Port latest set of changes from iu-workflow over to iu-rice, also, examine for any new changes to Rice 0.9.1.4 that we need to account for
    • Rice Module:
      KRAD
    • KRAD Feature Area:
      Persistence Framework
    • Application Requirement:
      KFS, KC
    • Sprint:
      Core 2.5.0-m6 Sprint 2
    • KAI Review Status:
      Not Required
    • KTI Review Status:
      Not Required
    • Code Review Status:
      Not Required
    • Include in Release Notes?:
      Yes
    • Story Points:
      13

      Description

      KC uses the deep copy related methods in the ObjectUtils.java class when it does a deep copy of objects. Specifically, the methods that materialize proxies. What this method does is it recursively gets all the proxies in an object and materializes them so that when you serialize later on, all those objects are available. This method takes advantage of some OJB methods and those obviously no longer work for JPA managed objects. These methods ( materializeSubObjectsToDepth and the related ones are the ones I am aware of) need to be ported over to JPA into a new utils class but I am not seeing where this has been done and I think is missing functionality. We'd like a generic way to materialize proxies if possible. Currently the way I've fixed this in KC is to use reflection to grab all of the lists and manually materialize them and that seems clunky and I'd rather use JPA to do some work for me, atleast give me a way to just get the proxies. Also, the other thing I've noticed is that Rice has dealt with the same issue in a number of different ways in its code base
      https://jira.kuali.org/issues/?jql=text%20~%20%22An%20attempt%20was%20made%20to%20traverse%20a%20relationship%20using%20indirection%20that%20had%20a%20null%22

      I think we need a more generic and standard solution for this.

        Issue Links

          Activity

          Hide
          Jonathan Keller added a comment -

          As discussed in the Skype chat, we may be able to use the DataObjectWrapper class and new methods there to perform this function. We have the needed metadata there to know the relationships which might need to be resolved.

          Show
          Jonathan Keller added a comment - As discussed in the Skype chat, we may be able to use the DataObjectWrapper class and new methods there to perform this function. We have the needed metadata there to know the relationships which might need to be resolved.
          Hide
          Jonathan Keller added a comment - - edited

          Looks like the implementation in fetchRelationship() is what we want.

          I propose adding a materializeReferencedObjectsToDepth( int depth, MaterializeOptions... options ) method to the DataObjectWrapper class.

          This would go through all the metadata-stored relationships and run the fetchRelationship method on them.

          Options would be:

          REFERENCES Refresh one-to-one or many-to-one references (default is both)
          COLLECTIONS Refresh one-to-many or many-to-many references (default is both)
          UPDATE_UPDATABLE_REFS Refresh updatable references in addition to read-only references (which are always refreshed) - note that this would destroy any unsaved data on updatable objects, as they will be reloaded from the database
          NULL_INVALID_REFS If a referenced object does not exist in the database, null the object. Default is to leave the object in place.
          INCLUDE_EAGER_REFS By default, it would only refresh lazy (proxied) references. Include this to refresh eager references which may not have been populated.
          Show
          Jonathan Keller added a comment - - edited Looks like the implementation in fetchRelationship() is what we want. I propose adding a materializeReferencedObjectsToDepth( int depth, MaterializeOptions... options ) method to the DataObjectWrapper class. This would go through all the metadata-stored relationships and run the fetchRelationship method on them. Options would be: REFERENCES Refresh one-to-one or many-to-one references (default is both) COLLECTIONS Refresh one-to-many or many-to-many references (default is both) UPDATE_UPDATABLE_REFS Refresh updatable references in addition to read-only references (which are always refreshed) - note that this would destroy any unsaved data on updatable objects, as they will be reloaded from the database NULL_INVALID_REFS If a referenced object does not exist in the database, null the object. Default is to leave the object in place. INCLUDE_EAGER_REFS By default, it would only refresh lazy (proxied) references. Include this to refresh eager references which may not have been populated.
          Hide
          Gayathri Athreya added a comment - - edited

          This sounds good. In KC I was trying to recursively get all methods returning lists using reflection and trying to materialize the entities in the list BUT it did not work for cases like this

          EntityA.java
           @ManyToOne(targetEntity = EntityB.class, cascade = { CascadeType.REFRESH })
           @JoinColumn(name = "JOIN_COLUMN", insertable = false, updatable = false)
           private EntityB b;
          
          EntityB.java
          @OneToMany(mappedBy = "entityB")
           private List<EntityC> entityCs;
          

          When I use reflection to get all methods that return a list, I obviously miss the manyToOne relationship above which in turn has a oneToMany which is lazy loaded that I never get to. But I think if you do get the REFERENCES as listed above, you will catch these too and materialize ALL lazy loaded objects.

          Show
          Gayathri Athreya added a comment - - edited This sounds good. In KC I was trying to recursively get all methods returning lists using reflection and trying to materialize the entities in the list BUT it did not work for cases like this EntityA.java @ManyToOne(targetEntity = EntityB.class, cascade = { CascadeType.REFRESH }) @JoinColumn(name = "JOIN_COLUMN" , insertable = false , updatable = false ) private EntityB b; EntityB.java @OneToMany(mappedBy = "entityB" ) private List<EntityC> entityCs; When I use reflection to get all methods that return a list, I obviously miss the manyToOne relationship above which in turn has a oneToMany which is lazy loaded that I never get to. But I think if you do get the REFERENCES as listed above, you will catch these too and materialize ALL lazy loaded objects.
          Hide
          Jonathan Keller added a comment -

          Eric/Peter,

          When you have a chance, could you please look at my proposal in the earlier comment and make sure that it's an OK method (and enum) to add to our KRAD Data APIs?

          Thanks.

          Show
          Jonathan Keller added a comment - Eric/Peter, When you have a chance, could you please look at my proposal in the earlier comment and make sure that it's an OK method (and enum) to add to our KRAD Data APIs? Thanks.
          Hide
          Kristina Taylor (Inactive) added a comment -

          Probably should do a code review on this as well.

          Show
          Kristina Taylor (Inactive) added a comment - Probably should do a code review on this as well.

            People

            • Assignee:
              Jonathan Keller
              Reporter:
              Gayathri Athreya
            • Votes:
              1 Vote for this issue
              Watchers:
              7 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved:

                Agile

                  Structure Helper Panel