Skip to end of metadata
Go to start of metadata

Agenda

  • Ensure that code that Heath and Aaron have been working on is easily accessible, either through GitHub or pushed to Kuali SVN server
    • KRAD poc
    • Pizza Store - JPA testbed
  • List out Goals for the Week
  • Summarize findings from JPA poc work so far
  • Work together to distill from this if we have arrived at a best solution for managing the lifecycle of JPA entities in terms of detachment and lazy loading within the document framework and other parts of KRAD
  • Begin to sketch out a rough design for how this might slot into the document framework
    • keeping in mind the requirement to store this data in intermediate format during routing
    • talk about Aaron's conversation scope as well, should we look to utilize something like this?
    • identity the main KRAD services that will need to be mapped to JPA
    • design around general abstract of data layer in KRAD for use with non-OJB, non-JPA scenarios?
  • Continue work on a POC around this design in KRAD framework
  • Talk about the "existence checks" built into the framework and how this would work with JPA
  • Talk about design of extension framework, possible POC around this
  • Talk about design of ID generation, possible POC around this
  • As much knowledge transfer as possible done during the week
  • Can we push for JPA in KRAD phase 2 or 3 as an "experimental but not officially supported" feature? Just so that we can begin to get the framework in place?

Work Done So Far

Goals for the Week

  1. Would like to have a good idea of how we are going to implement JPA support in KRAD document framework.
  2. Build out the KRAD poc to utilize JPA.
  3. Have a design for how to deal with Extension Framework.
  4. Have a design or approach for how to deal with business rule validation patterns.

Summary of Findings So Far

  1. ID Generation - boils down to what is going to work in your environment
    • general approach of scaling that back to a single table and pull caches of ids at any given time
    • each of us should take one of the 3 jpa providers and find out how they grab new sequence values in the "per-table" model
  2. Multiple Persistence Units in same container using different providers - we know this is possible
    • it's possible, fires up no problem
    • only problem would be if you tried to maintain different problems of your hierarchical tree using different providers
    • so each persistence unit has to be separate
  3. Lazy loading, multiple options
    • eager load everything
      • possible, but not idea
    • do a custom load ourselves and pulling lazy associations ourselves
      • can use a transient extended entity manager to load these relationships
    • investigating an extended persistence context
      • possible, but since you are dealing with a programatic entity manager, you now have to deal with the lifespan, it complicates code significantly
      • there are still questions regarding rollbacks
  4. Reattaching and Preventing Persist
    • if we get a new extended entity manager and merge a modified entity into it, it does not insert or update records, even if we modify the merged object after the merge
    • neither one will be inserted whether it's managed or unmanaged as long as it's an extended entity manager
    • for extended entity manager, updates don't happen until you attach it to a transaction
  5. Seems we need to have two sets of entity managers, one for transactional operation and one for lazy loading
  6. JPA Metamodel only provides information on logical metadata, not physical metadata. In otherwords, we can't find out information about column names, join columns, etc. which will prevent us from implementing some portions of PersistenceStructureService.
    • So far we've found this will prevent us from implementing methods like getReferencesForForeignKey.
    • One way to work around this would be to drop to the vendor-specific metadata. I believe, at least in Hibernate, this information about column metadata is available. But we would need to build an appropriate abstraction layer in to allow us to plug-in specific provider implementations for this metadata.
    • We also need to determine if other JPA vendors can provide this kind of information.
  7. In JPA, it appears that many relationships need to be bidirectional. For example, if you have a @OneToMany from an account to expenses, the expenses needs to have a @ManyToOne back to the account. In these scenarios, it's required that both sides of the bidirectional relationship need to be established.
    • It doesn't look like we are currently doing this in the collection framework as it exists today.

Action Items

  1. Each of us should take one of the JPA vendors and determine how they handle TABLE id generation from a locking/contention perspective.
    1. Status: IdGeneration tests are in place for EclipseLink, Hibernate, OpenJPA (requires weaving agent); ToppingType has been converted to use TABLE generation type. Load tests show lock contention. Tests are Ignored for now. Todo: 1) Implement on Oracle 2) test effectiveness of allocation size as contention remedy 3) test w/ multiple entities and w/ separate tables (for functionality and as a remedy to contention)
    2. UPDATE: I changed the DB to initialize at 100 for the sequence numbers and everything seems to be working as expected without any locking.  I implemented TABLE generation type for eclipselink without issue, but the same setting on hibernate do not work until I switched the JPA transaction manager to atomikos, then both the eclipselink and hibernate worked as expected.  IDENTITY, and AUTO work without issue on hibernate in both transaction implementations.
    3. NOTE: seq table with hibernate will increment based on the allocation size (so allocation size of 1000 will generate a 5 in the seq table if 4500 recs are inserted).  So changing this allocation size maybe dangerous in some regards and cause the reuse of ids.
  2. Determine how we can handle backward compatibility for old Rice code.
    • PrePersist hook, look at OrmUtils.populateAutoIncValue
    • UPDATE: After testing this concept in the jpa-testbed, I am not sure if it was working in the previous JPA implementation in RICE.  I in the test, neither eclipselink or hibernate would allow the use of entity manager in a callback jpa annotation like @PrePersist. Page 93 of the JPA 2.0-final spec states: 

      In general, the lifecycle method of a portable application should not invoke EntityMan- ager or Query operations, access other entity instances, or modify relationships within the same persistence context.[43] A lifecycle callback method may modify the non-relationship state of the entity on which it is invoked. 

  3. Build a sample client application which uses three persistence units, configured via spring, not using JTA, but using spring managed transactions, and verify that during a transaction even though it uses three persistence units that it uses the same connection to the database.
    • this help us determine how we design the KRAD persistence unit
    • particularly in relation to documents and the transdoc framework
    • UPDATE: As long as the data source is "transaction aware" in relation to Spring (meaning it's wrapped by a TransactionAwareDataSourceProxy) then entity managers from multiple entity manager factories will "bind" to the same connection from a given datasource.#-* See poc project for this here: http://svn.kuali.org/repos/rice/sandbox/jpa-2.x-pocs/spring-tx-jpa-poc/
  4. Test the following scenario:
    • An object with a lazy loaded collection, load an object using JPA which has nothing in that collection, detach it but don't trigger loading of the lazy collection (try with and without calling size), then try to add a new object to the collection after it's detached  UPDATE: there are tests in place that practice these scenarios on the jpa-testbed project.
    • does it trigger a lazy initialization exception? UPDATE: it will if you use EXTRA lazy loading (configurable in hibernate)..... DON'T use extra lazy.
  5. Setup the JPA lookupJPADAO object using the JPA 2.0 CriteriaBuilder API.
    • Created a new lookup object using the criteria builder called LookupCriteriaBuilderJPADAO
    • Change out the in house criteria object to use the JPA CriteriaBuilder UPDATE: changed out the criteria object for the CriteriaBuilder and tested using the current JPA object (TravelAccountJPA).  Was able to setup the test to handle the wildcarding and the multiple search fields.  Also, setup for primary key searches.  
    • NOTE: The aliases are setup by the 'join' command and can be defined based on the selection criteria.

Steps for Setting up KRAD Codebase for JPA POC

  1. Set up a way to identify that a particular business object will be using JPA
    • UPDATE: Created an @JpaForReals annotation which could be used on an object to indicate it should be considered by Rice for JPA. This is meant to just be a temporary solution! Original code in OrmUtils.isJpaAnnotated was checking whether or not there was a JPA annotation on the class. We have a bunch of classes in Rice that have old JPA annotations on them. Wanted to be able to do the POC with just a few jpa classes and the rest of the system still running OJB.
  2. Verify that MetadataManager is working properly for JPA. As part of this PersistenceStructureService needs to be implemented properly such that it delegates to the JPA version of the backend impl.
  3. Modify the ModuleConfiguration so that it stores an EntityManagerFactory (the special LocalContainerEntityManagerFactoryBean) one, instead of storing an EntityManager. Change it so that we are injecting EntityManagerFactory instead of EntityManager as well.
    • UPDATE: just modified it so that it has a getEntityManagerFactory method which calls entityManager.getEntityManagerFactory
  4. Ensure that BusinessObjectDaoProxy is properly switching context to JPA for our @JpaForReals objects.
    • UPDATE: hacked this into place (see TODO in getDao method)
  5. Need to determine how best to handle entities with embedded identifiers (for compound primary keys), with the PersistenceStructureService. May require some redesign of how PersistenceStructureService deals with PK's. Should be able to do some amount of POC around this I would think. Should have support for:
    • @IdClass
    • @EmbeddedId
  6. Need to figure out the best way to deal with Embedded types in JPA. We could initially just not build in support for them, but should track that's not the case and ensure we add support for them later.
  7. We should add caching to PersistenceStructureService using @Cachable. There's no reason that stuff can't be cached.
  8. Need to get rid of "ReferenceAttributeNotAnOjbReferenceException".
  9. Hack the Document controller in KRAD so that it reattaches documents stored up in the session
  • No labels