persistence@glassfish.java.net

Re: [Issue 756] Cache-related query hints have no effect?

From: Christopher Delahunt <christopher.delahunt_at_oracle.com>
Date: Wed, 23 Aug 2006 14:11:52 -0400

Hello Wonseok,

You are correct. The cache-usage hint is a hold over from when TopLink used ReadObject/ReadAllQuery types. When JPL was changed to support multiple return types, TopLink switched to using ReportQueries internally but the cache-usage hint was overlooked. I believe the intention was to revist this change, since ReportQueries always go to the database, which is why the hint might have been overlooked. It should be removed and the documentation changed.

I've filed bug 999 so it gets looked at.

Best Regards,
Chris


  ----- Original Message -----
  From: Wonseok Kim
  To: persistence_at_glassfish.dev.java.net
  Sent: Monday, August 21, 2006 10:19 PM
  Subject: Re: [Issue 756] Cache-related query hints have no effect?


  Hi, everyone


  I think that cache-usage hint have no effect at all. There is no difference in the result for any cache-usage value. Always query goes to database without checking cache (DoNotCheckCache, CheckCacheThenDatabase,... whatever it is, same behaviour).
  And if CheckCacheOnly, it throws an exception like below code.(then why this value is documented?)

  This is because JPQL SELECT is implemented by TopLink ReportQuery. ReportQuery seems not to support cache-usage. When I see the code - DatabaseQuery.execute() and checkEarlyReturn(),
  ReportQuery.checkEarlyReturnImpl() doesn't do anything but for checking invalid cache-usage.

  So is this intended or need to be fixed? Maybe any TopLink guy can explain this.
  - Wonseok

  [code]
  Query query = em.createQuery("SELECT e FROM Employee e");

  query.setHint("toplink.cache-usage", "CheckCacheOnly");
  List list5 = query.getResultList();//throws Exception: Cannot set ReportQuery to "check cache only".
  printEmployeeList(list5, "CheckCacheOnly");

  [exception]
  Local Exception Stack:
  Exception [TOPLINK-6090] (Oracle TopLink Essentials - 2006.8 (Build 060818)): oracle.toplink.essentials.exceptions.QueryException
  Exception Description: Cannot set ReportQuery to "check cache only".
  Query: ReportQuery(jpatest.entities.Employee)
      at oracle.toplink.essentials.exceptions.QueryException.cannotSetShouldCheckCacheOnlyOnReportQuery(QueryException.java:386)
      at oracle.toplink.essentials.queryframework.ReportQuery.checkEarlyReturnImpl (ReportQuery.java:644)
      at oracle.toplink.essentials.queryframework.ObjectLevelReadQuery.checkEarlyReturn(ObjectLevelReadQuery.java:429)
      at oracle.toplink.essentials.queryframework.DatabaseQuery.execute(DatabaseQuery.java :556)
      at oracle.toplink.essentials.queryframework.ObjectLevelReadQuery.execute(ObjectLevelReadQuery.java:677)
      at oracle.toplink.essentials.queryframework.ObjectLevelReadQuery.executeInUnitOfWork(ObjectLevelReadQuery.java :731)
      at oracle.toplink.essentials.internal.sessions.UnitOfWorkImpl.internalExecuteQuery(UnitOfWorkImpl.java:2218)
      at oracle.toplink.essentials.internal.sessions.AbstractSession.executeQuery(AbstractSession.java :937)
      at oracle.toplink.essentials.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:909)
      at oracle.toplink.essentials.internal.ejb.cmp3.base.EJBQueryImpl.executeReadQuery(EJBQueryImpl.java :346)
      at oracle.toplink.essentials.internal.ejb.cmp3.base.EJBQueryImpl.getResultList(EJBQueryImpl.java:447)
      at jpatest.JpaTest.testCacheUsage(JpaTest.java:423)



  On 21 Aug 2006 19:27:29 -0000, chris_delahunt_at_dev.java.net < chris_delahunt_at_dev.java.net> wrote:
  https://glassfish.dev.java.net/issues/show_bug.cgi?id=756


  ------- Additional comments from chris_delahunt_at_dev.java.net Mon Aug 21 19:27:29 +0000 2006 -------
  This is more a misunderstanding of what setHint("toplink.cache-usage", 0) does
  than a bug. TopLink will first use the expression to search the cache. If it
  finds the object there it will return it, if not, it will go to the database.

  Setting the toplink.cache-usage hint to 0 will prevent TopLink from initially
  going to the cache, and so go directly to the database.

  After it gets results from the database, it then uses the primary keys to
  search the cache for those objects. If they exist, they get returned, If they
  don't, they get built and placed in the cache - all to maintain object
  identity.

  The toplink.refresh is used to tell TopLink that the object in the cache needs
  to be refreshed when the query comes back from the database. Using both
  toplink.cache-usage and toplink.refresh will ensure that a query will go to the
  database and returned refreshed data. The alternative is to use the em.refresh
  () api.