5 Replies Latest reply on Feb 9, 2009 8:48 AM by Ryan LaMothe

    Why does em.persist resets the Query cache?

    Onur AKTAS Newbie

      Hi,

      Why new inserted items resets the Query cache?

      Query query = em.createQuery("select b from Book where id < 5");
      query.setCacheable("org.hibernate.cacheable", true);
      query.getResultList(); // RETRIEVES FROM DATABASE;
      
      query.getResultList() // RETRIEVES FROM CACHE -> OK!
      
      Book book = new Book();
      book.setTitle("Test 1 2 3");
      em.persist(book);
      System.out.println(book.getId()); // ----> For example: Returns 200
      
      // Book having ID 1 is inserted before, it is not the persisted one above.
      query.getResultList(); ---> RETRIEVES FROM DATABASE
      


        • 1. Re: Why does em.persist resets the Query cache?
          Ryan LaMothe Newbie

          [list=]Do you have Hibernate second-level configured and enabled?
          [list=]What are doing to test that #1 is true?

          • 2. Re: Why does em.persist resets the Query cache?
            Onur AKTAS Newbie

             

            "ryanrlamothe" wrote:
            [list=]Do you have Hibernate second-level configured and enabled?
            [list=]What are doing to test that #1 is true?


            It is true i both check database query logs and also hibernate.show_sql is enabled that i can see from terminal.
            And yes, hibernate secondary-level cache is configured and enabled.

            • 3. Re: Why does em.persist resets the Query cache?
              Ryan LaMothe Newbie

              Well, first of all, query caching is only for named queries.

              So, you will need to create an entity which has the following annotation (or XML configuration):

              @NamedQueries( { @NamedQuery(name = "Book.findByIdCustom", query = "select b from Book b where b.id < :id") })


              Where Book is your entity and id is a field in your entity.

              Then you will need to create the following code in your facade:

              Query query = entityManager.createNamedQuery("Book.findByIdCustom");
              query.setParameter("id", id);
              query.setHint("org.hibernate.cacheable", true);
              return query.getResultList();



              Now, you will need to be careful to evict the query results appropriately to avoid getting stale data in your results.

              • 4. Re: Why does em.persist resets the Query cache?
                Onur AKTAS Newbie

                I think its not for just named queries because it works when i do not persist anything.
                It caches normal queries, and also you can mark @QueryHint to obtain caching for named queries.

                To sum up, i think there is no solution for this situation, out of controlling the cache manually.

                • 5. Re: Why does em.persist resets the Query cache?
                  Ryan LaMothe Newbie

                  Here is some documentation for you to read concerning Query caching:
                  http://www.jboss.org/file-access/default/members/jbossas/freezone/docs/Clustering_Guide/4/html/ch04s02s03.html

                  Also, you really need to make sure your cache configuration is correct and that you are actually using the cache as designed. Which includes accurate and comprehensive unit tests, which it does not look like you are doing.

                  Manually controlling the query cache is not required for what you are doing. Honestly, the only manual query cache configuration you should need to do is manually evicting queries before their normal eviction period has expired, but you really only need to do that under very specific circumstances.

                  Which brings up another point...if you mark the queries as READ_ONLY then you would be guaranteed the database is only read once. But then you will need to make sure you inject the session manager and evict the query or query region in your entity facade whenever a save, update or delete occurs to a queried entity.