Jeff -

I'll recommit the changes in OPENJPA-2285 back to trunk on Monday. Will
those changes be sufficient for your scenarios?

Thanks,
Rick


On Fri, Feb 14, 2014 at 9:15 AM, Rick Curtis <curti...@gmail.com> wrote:

> Jeff -
>
> > As I said earlier, if there¹s work to be done, I¹m happy to submit a
> patch - but I¹d like some consensus around what the patch should do
> first...
> I talked with a few teammates yesterday and I think we're on the same page
> as you. I will do some digging to try to figure out why I backed this
> change out originally(rather than changed the testcase). I'll get you and
> update a bit later today.
>
> Thanks,
> Rick
>
>
> On Thu, Feb 13, 2014 at 12:41 PM, Jeff Oh <jeff...@elasticpath.com> wrote:
>
>> >As I eluded to in the JIRA, the root problem is that in the JPA 2.0 spec,
>> >the concept of Cache/CacheStoreMode/CacheRetrieveMode/etc/etc was added
>> >and
>> >this change was not honoring that contract. The crux of the problem is
>> >that
>> >the default value for CacheStoreMode is USE and the spec says[1] that
>> >elements in the cache are not to be updated. So in your example, after
>> >Foo-1[b,c] gets loaded the subsequent load of Foo-1[a] will not be
>> >reflected in the cache. I agree that most likely isn't the expected
>> >behavior, but we need to satisfy the spec.
>>
>>
>> Hmm.  So upon reading the spec, this is one possible interpretation of the
>> spec - but I¹m not sure that it¹s the only possible interpretation.
>>
>> The spec for CacheStoreMode.USE states:
>>
>>         /**
>>          * Insert/update entity data into cache when read
>>          * from database and when committed into database:
>>          * this is the default behavior. Does not force refresh
>>          * of already cached items when reading from database.
>>          */
>>
>> And the spec for CacheStoreMode.REFRESH states:
>>
>>         /**
>>          * Insert/update entity data into cache when read
>>          * from database and when committed into database.
>>          * Forces refresh of cache for items read from database.
>>          */
>>
>>
>> So the interesting thing is that CacheStoreMode.USE does not forbid
>> insert/update operations - it merely states that refreshes of already
>> cached items should not be ³forced².
>>
>>
>> I think there¹s multiple ways to interpret this.
>>
>> Assume we have an entity A with a eagerly fetched many-to-one relationship
>> to B.  If we load an instance of A from db, OpenJPA will almost certainly
>> also load B via a join when it issues the SQL select for A.  Normally, if
>> B is already in the L2 cache, and CacheStoreMode.USE is in effect, then I
>> agree that OpenJPA should not refresh the instance of B in the L2 cache.
>> However, if B is already in the L2 cache, *and* B¹s data loaded from the
>> db is both newer and different than B¹s representation in cache, then I
>> think there is a grey area in the spec.  Specifically, the spec does not
>> claim that the JPA implementation must refresh the item in cache, but it
>> also does not claim that the JPA implementation must not.  In an ideal
>> world, I think if JPA becomes aware that cached data is out of date it
>> should remove/replace it, and I don¹t think that anything in the spec
>> forbids this.  So ideally, in the second case, I claim that OpenJPA should
>> update the entity data for B in cache, even if the data is read using
>> CacheStoreMode.USE.
>>
>> I think that there is a similar argument to be had with the fetch group
>> example I used earlier.  CacheStoreMode.USE states that refreshes of
>> already cached items should not be forced, but it does not *forbid*
>> inserts and updates of already cached items when reading from the
>> database, particularly when reading data that was not already in cache.
>> Reading the JSR-317 spec (pg. 105) doesn¹t shed any more light in the
>> issue.
>>
>> While CacheStoreMode.REFRESH may be an option to work around this, it¹s
>> not a one-to-one replacement.  My worry is that using
>> CacheStoreMode.REFRESH instead of CacheStoreMode.USE is that depending on
>> the object model and the load, CacheStoreMode.REFRESH may prevent objects
>> from ever expiring from cache, because they¹re constantly being REFRESHed.
>>  Worse, the data merge mechanics mean that being refreshed in cache
>> doesn¹t necessarily imply that the data in cache is being refreshed as
>> well.  That could be a pretty significant downside for us.
>>
>> As I said earlier, if there¹s work to be done, I¹m happy to submit a patch
>> - but I¹d like some consensus around what the patch should do first...
>>
>>
>> Cheers,
>>
>> Jeff
>>
>> On 2/13/2014, 7:00 AM, "Rick Curtis" <curti...@gmail.com> wrote:
>>
>> >> Another question we have is what exactly was the "internal test
>> >regression" that caused the rollback?
>> >The company I work for (IBM) does a huge amount of functional server
>> based
>> >testing internally. When changes are made, the OpenJPA unit tests are the
>> >first line of tests and occasionally the UTs miss a scenario that the
>> >internal tests catch. This is one of those scenarios.
>> >
>> >As I eluded to in the JIRA, the root problem is that in the JPA 2.0 spec,
>> >the concept of Cache/CacheStoreMode/CacheRetrieveMode/etc/etc was added
>> >and
>> >this change was not honoring that contract. The crux of the problem is
>> >that
>> >the default value for CacheStoreMode is USE and the spec says[1] that
>> >elements in the cache are not to be updated. So in your example, after
>> >Foo-1[b,c] gets loaded the subsequent load of Foo-1[a] will not be
>> >reflected in the cache. I agree that most likely isn't the expected
>> >behavior, but we need to satisfy the spec.
>> >
>> >It might make sense to see how we behave if you change the CacheStoreMode
>> >to REFRESH. Start by passing the CacheStoreMode into
>> >EntityManager.find(...) and from there check to see if you can pass
>> >javax.persistence.CacheStoreMode as a persistence.xml level property.
>> >Honestly I don't have many cycles to look at this problem right now, but
>> >I'll help where I can.
>> >
>> >Thanks,
>> >Rick
>> >
>> >[1]
>> >*
>> http://docs.oracle.com/javaee/6/api/javax/persistence/CacheStoreMode.html
>> >#USE
>> ><
>> http://docs.oracle.com/javaee/6/api/javax/persistence/CacheStoreMode.html
>> >#USE>*
>> >--
>> >"Does not force refresh of already cached items when reading from
>> >database."
>> >
>> >On Wed, Feb 12, 2014 at 5:03 PM, Jeff Oh <jeff...@elasticpath.com>
>> wrote:
>> >
>> >> Hello,
>> >>
>> >> We're currently migrating an application from OpenJPA 1.2.2 to OpenJPA
>> >> 2.3.0, and have found that DataCache efficacy in our application
>> >>declines
>> >> significantly from 1.2.2 to 2.3.0, to the point where our overall
>> system
>> >> performance has declined by about 25% with the version upgrade.
>> >>
>> >> We've found that we can restore DataCache performance to 1.2.2 levels
>> by
>> >> re-applying OPENJPA-2285<
>> >> https://issues.apache.org/jira/browse/OPENJPA-2285>, which was rolled
>> >> back due to an "internal test regression" issue.
>> >>
>> >> The behaviour we've found is this:
>> >>
>> >> Given:
>> >>
>> >> An entity Foo, with fields [a, b, c].
>> >> Foo-1 is loaded into the datacache using a fetch group that loads
>> fields
>> >> [a, b].
>> >>
>> >> When:
>> >>
>> >> A query is executed that loads Foo-1 using fields [b,c].  This query is
>> >> executed twice in succession, using two different EntityManagers.
>> >>
>> >> Then:
>> >>
>> >> In OpenJPA 2.3.0, both queries result in a SQL query being run to load
>> >>the
>> >> value of field c.
>> >> In OpenJPA 1.2.2, only the first query results in a SQL query being run
>> >>to
>> >> load the value of field c.  The second query is serviced from cache.
>> >>
>> >> Expected:
>> >>
>> >> The OpenJPA 1.2.2 behaviour seems more consistent with expected cache
>> >> behaviour.  The cache cannot be expected to successfully fulfill the
>> >> request on the first invocation - but it should be able to fulfill it
>> on
>> >> all subsequent invocations.
>> >>
>> >> The first question is, what should OpenJPA 2's behaviour be in this
>> >> circumstance?  OPENJPA-2285<
>> >> https://issues.apache.org/jira/browse/OPENJPA-2285> merges the new
>> >>loaded
>> >> fields into the original cached entity and recaches the entity.
>>  OpenJPA
>> >> 1.2.2 does a similar thing, except that it rejects the merge if the new
>> >> entity has an earlier version than the cached entity.  Note that
>> merging
>> >> still occurs in OpenJPA 1.2.2 if the new entity has a later version
>> than
>> >> the cached entity.
>> >>
>> >> Another question we have is what exactly was the "internal test
>> >> regression" that caused the rollback?
>> >>
>> >>
>> >> Some potential solutions:
>> >>
>> >> 1. Merge cached and loaded data as per OPENJPA-2285/OpenJPA 1.2.2.
>> >> This minimizes database operations required.  On the other hand, the
>> >>merge
>> >> of cached and non-cached data raises the possibility of entities with
>> >> "mixed" data from various versions.  It's probably best to reject the
>> >> object entirely if a version conflict is detected and reload the entire
>> >> object from the db (and recache) in that instance.
>> >>
>> >> 2. Load object from db using the query's fetch group and recache.
>> >> Instead of merging cached fields and db loaded fields, OpenJPA could
>> >>load
>> >> the entire object using the query's fetch group.  This object should be
>> >>in
>> >> a consistent state, and the object in data cache could be replaced with
>> >>the
>> >> newly loaded object.  The disadvantage would be if there are two
>> >>different
>> >> queries being run for the same entity, one with the fetch group [a, b]
>> >>and
>> >> another with the fetch group [b,c], then the object in cache will
>> >>"whipsaw"
>> >> back and forth between representations.  This also results in more db
>> >> access than option #1.
>> >>
>> >> 3. Load object from db using the superset of the query's fetch group
>> and
>> >> the datacache's fetch group and recache.
>> >> Instead of merging cached fields and db loaded fields, OpenJPA could
>> >>load
>> >> the entire object using the union of the query's fetch group and the
>> >>cached
>> >> entities' fetch group.  This object should be in a consistent state,
>> and
>> >> the object in data cache could be replaced with the newly loaded
>> object.
>> >>  The disadvantage would be it's hard to see how this could reliably
>> >>extend
>> >> to entities related to the original entity that are loaded as part of
>> >>the
>> >> query.  However, it avoids the whipsaw problems in option #2.  This
>> >>option
>> >> also results in the most db access, at least initially.
>> >>
>> >> 4. Remove incomplete entities from cache.
>> >> Merge cached and loaded data together as is done currently, but remove
>> >>the
>> >> cached entity afterwards.  This isn't much of a solution, but at least
>> a
>> >> sparsely loaded entity doesn't have the potential to degrade the cache
>> >> indefinitely...
>> >>
>> >> 5. Some ability to enable one or more of the solutions via a config
>> >> option, if none of these solutions are considered acceptable for "core"
>> >>use.
>> >>
>> >>
>> >> If there's agreement on what behaviour folks would like to see, I'd be
>> >> happy to submit a patch.
>> >>
>> >>
>> >> Cheers,
>> >>
>> >> Jeff
>> >>
>> >>
>> >>
>> >>
>> >>
>> >>
>> >>
>> >> [http://elasticpath.com/images/ep.gif]
>> >> Jeff Oh, Sr. Software Engineer
>> >> Phone: 604.408.8078 ext. 104
>> >> Email: jeff...@elasticpath.com<mailto:jeff...@elasticpath.com>
>> >>
>> >> Elastic Path Software Inc.
>> >> Web elasticpath.com <http://www.elasticpath.com/> | Blog
>> getelastic.com
>> >><
>> >> http://www.getelastic.com/> | Twitter twitter.com/elasticpath <
>> >> http://www.twitter.com/elasticpath>
>> >> Careers elasticpath.com/jobs<http://www.elasticpath.com/jobs> |
>> >>Community
>> >> grep.elasticpath.com <http://grep.elasticpath.com/>
>> >>
>> >> Confidentiality Notice: This message is intended only for the use of
>> the
>> >> designated addressee(s), and may contain information that is
>> privileged,
>> >> confidential and exempt from disclosure. Any unauthorized viewing,
>> >> disclosure, copying, distribution or use of information contained in
>> >>this
>> >> e-mail is prohibited and may be unlawful. If you received this e-mail
>> in
>> >> error, please reply to the sender immediately to inform us you are not
>> >>the
>> >> intended recipient and delete the email from your computer system.
>> >>
>> >>
>> >>
>> >>
>> >
>> >
>> >--
>> >*Rick Curtis*
>>
>>
>>
>>
>> Jeff Oh, Sr. Software Engineer
>> Phone: 604.408.8078 ext. 104
>> Email: jeff...@elasticpath.com
>>
>> Elastic Path Software Inc.
>> Web: www.elasticpath.com
>> Blog: www.getelastic.com
>> Community: grep.elasticpath.com
>> Careers: www.elasticpath.com/jobs
>>
>> Confidentiality Notice: This message is intended only for the use of the
>> designated addressee(s), and may contain information that is privileged,
>> confidential and exempt from disclosure. Any unauthorized viewing,
>> disclosure, copying, distribution or use of information contained in this
>> e-mail is prohibited and may be unlawful. If you received this e-mail in
>> error, please reply to the sender immediately to inform us you are not the
>> intended recipient and delete the email from your computer system. Thank
>> you.
>>
>>
>>
>
>
> --
> *Rick Curtis*
>



-- 
*Rick Curtis*

Reply via email to