-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 9 posts ] 
Author Message
 Post subject: query returns different result that are in cache
PostPosted: Tue Dec 26, 2017 1:43 pm 
Newbie

Joined: Tue Dec 26, 2017 1:31 pm
Posts: 5
Hi,
Using hiber 4.1.11.Final, ehcache 2.10.2
I have enabled second level cache, query cache.
Product entity has @Cache annotation.
Have a page that display some info about product. Info about product is fetched with criteria query that is cachable.
query.setHint("org.hibernate.cacheable", true);
query.setHint("org.hibernate.cacheRegion", "query.Products");
I access the page with product once - to get product in cache. See that value that comes from column "A" corresponds with the value in DB.
do direct db update - with sql, change value in text column "A".
Refresh page with product ~5 times, see that value from column "A" "blinks" sometimes it shows old, sometimes it shows new.
I put breakpoint and see that even query returns new value cache containt old one.
I would expect that I will not see new value until cache expires or I invalidate cache.
Any ideas, hints, suggestions how it is possible that criteria query might ignore cache or get new value from db and not updating cache?


Top
 Profile  
 
 Post subject: Re: query returns different result that are in cache
PostPosted: Tue Dec 26, 2017 2:20 pm 
Hibernate Team
Hibernate Team

Joined: Thu Sep 11, 2014 2:50 am
Posts: 1628
Location: Romania
You need to show the entity mapping and the data access code as well. Also, turn on the JDBC log to see what statements are executed. Check out this article for more details.


Top
 Profile  
 
 Post subject: Re: query returns different result that are in cache
PostPosted: Wed Dec 27, 2017 3:47 am 
Newbie

Joined: Tue Dec 26, 2017 1:31 pm
Posts: 5
Code:
@Entity
@Inheritance(strategy = InheritanceType.JOINED)
@javax.persistence.Table(name = "BLC_PRODUCT")
@org.hibernate.annotations.Table(appliesTo = "BLC_PRODUCT", indexes = {
        @Index(name = "PRODUCT_URL_INDEX",
                columnNames = {"URL", "URL_KEY"}
        )
})
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE, region = "blProducts")
public class ProductImpl implements Product{
    @Id
    @GeneratedValue(generator = "ProductId")
    @GenericGenerator(
            name = "ProductId",
            strategy = "org.broadleafcommerce.common.persistence.IdOverrideTableGenerator",
            parameters = {
                    @Parameter(name = "segment_value", value = "ProductImpl"),
                    @Parameter(name = "entity_name", value = "org.broadleafcommerce.core.catalog.domain.ProductImpl")
            })
public class ProductImpl implements Product{
    @Column(name = "PRODUCT_ID")
    protected Long id;

    @Column(name = "MANUFACTURE")
    protected String manufacturer;

    @Column(
        name = "URL_KEY"
    )
    protected String urlKey;

.....

}


Code:
        CriteriaBuilder builder = this.em.getCriteriaBuilder();
        CriteriaQuery<Product> criteria = builder.createQuery(Product.class);
        Root<ProductImpl> product = criteria.from(ProductImpl.class);
        FetchParent fetchParent = product.fetch("defaultSku", JoinType.LEFT);
        criteria.select(product);
        List<Predicate> restrictions = new ArrayList();
        restrictions.add(builder.equal(product.get("urlKey"), urlKey));
        restrictions.add(builder.or(builder.isNull(product.get("defaultSku").get("activeEndDate")), builder.greaterThan(product.get("defaultSku").get("activeEndDate").as(Date.class), this.getCurrentDateAfterFactoringInDateResolution())));
        criteria.where((Predicate[])restrictions.toArray(new Predicate[restrictions.size()]));
        TypedQuery<Product> query = this.em.createQuery(criteria);
        query.setHint("org.hibernate.cacheable", true);
        query.setHint("org.hibernate.cacheRegion", "query.Catalog");
        List<Product> results = query.getResultList();



Top
 Profile  
 
 Post subject: Re: query returns different result that are in cache
PostPosted: Wed Dec 27, 2017 5:04 am 
Newbie

Joined: Tue Dec 26, 2017 1:31 pm
Posts: 5
I might suspect that because we use date/time parameter in query and it is basicly system time at the time of request this will result in almost always a cache miss for collection.
Maybe my understanding of how cache is working:
When there is a "hit" to collection cache it take id from that cache and looks in apropriate cache region if there is entity with such id, if so returns that entity.

When there is a miss to collection cache. What will it do? will take only id from the result of db query and try to find entity in appropriate cache region, or will it use result of the query as a final result, and so will not query cache region ?


Top
 Profile  
 
 Post subject: Re: query returns different result that are in cache
PostPosted: Wed Dec 27, 2017 9:17 am 
Hibernate Team
Hibernate Team

Joined: Thu Sep 11, 2014 2:50 am
Posts: 1628
Location: Romania
When there is a cache miss for the query, it will just run the query and the entities will be used from the 2nd-level cache during two-phase loading.

Check out this article for more details.


Top
 Profile  
 
 Post subject: Re: query returns different result that are in cache
PostPosted: Wed Dec 27, 2017 9:29 am 
Newbie

Joined: Tue Dec 26, 2017 1:31 pm
Posts: 5
thx, then, I'm not sure what else might be wrong.
after a miss in query cache, it should use id and load from 2nd level cache, instead it looks like it takes results from query, as I see that in the 2nd level cache still old entity for that key...
If there is no cache miss to a query cache then it take entity from cache...

Maybe you can suggest where to put breakpoint in hibernate classes to see what's going on ?


Top
 Profile  
 
 Post subject: Re: query returns different result that are in cache
PostPosted: Wed Dec 27, 2017 10:29 am 
Hibernate Team
Hibernate Team

Joined: Thu Sep 11, 2014 2:50 am
Posts: 1628
Location: Romania
You can add the breakpoint in the get method of StandardQueryCache.


Top
 Profile  
 
 Post subject: Re: query returns different result that are in cache
PostPosted: Wed Dec 27, 2017 11:55 am 
Newbie

Joined: Tue Dec 26, 2017 1:31 pm
Posts: 5
Thank you.
I debugged a bit, and can't find the place where in case of a miss in query cache it will load entity from 2nd level cache - from what I understand it uses result of a query as a final result


Top
 Profile  
 
 Post subject: Re: query returns different result that are in cache
PostPosted: Wed Dec 27, 2017 2:06 pm 
Hibernate Team
Hibernate Team

Joined: Thu Sep 11, 2014 2:50 am
Posts: 1628
Location: Romania
Yes, it's for the first-level cache only:

Code:
//If the object is already loaded, return the loaded one
object = session.getEntityUsingInterceptor( key );
if ( object != null ) {
   //its already loaded so don't need to hydrate it
   instanceAlreadyLoaded(
         rs,
         i,
         persisters[i],
         key,
         object,
         lockModes[i],
         session
   );
}
else {
   object = instanceNotYetLoaded(
         rs,
         i,
         persisters[i],
         descriptors[i].getRowIdAlias(),
         key,
         lockModes[i],
         optionalObjectKey,
         optionalObject,
         hydratedObjects,
         session
   );
}


So, if there is a cache miss, it will use thee ResultSet, unless the entity is in the Persistence Context (e.g. EntityManager or Session).


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 9 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.