-->
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.  [ 16 posts ]  Go to page 1, 2  Next
Author Message
 Post subject: Hibernate Query Cache does not work with JCache and Ehcache
PostPosted: Thu Oct 12, 2017 9:03 am 
Newbie

Joined: Thu Oct 12, 2017 8:41 am
Posts: 8
Hi
I'm new to tomcat/hibernate and I want to use ehcache 3.
I followed many tutorials and samples on the web, but could not make it work. The application itself works perfectly but all queries are sent to mysql, none are cached. Any help will be greatly appreciated.

Main libraries :
ehcache-3.3.1.jar
ehcache-api-3.3.1.jar
ehcache-core-3.3.1.jar
hibernate-commons-annotations-5.0.1.Final.jar
hibernate-core-5.2.10.Final.jar
hibernate-jcache-5.2.10.Final.jar
hibernate-jpa-2.1-api-1.0.0.Final.jar
etc.

persistence.xml:
Code:
  <persistence-unit name="ric">
    <class>Global.User</class>
    <properties>
      <property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect"/>
      <property name="hibernate.connection.datasource" value="java:comp/env/jdbc/tomcattest"/>
      <property name="hibernate.cache.use_second_level_cache" value="true"/>
      <property name="hibernate.cache.use_query_cache" value="true"/>
      <property name="hibernate.javax.cache.provider" value="org.ehcache.jsr107.EhcacheCachingProvider"/>
      <property name="hibernate.cache.region.factory_class" value="org.hibernate.cache.jcache.JCacheRegionFactory"/>
      <property name="hibernate.show_sql" value="false"/>
    </properties>
  </persistence-unit>


Persistent object :
Code:
import org.hibernate.annotations.Cache;
import org.hibernate.annotations.CacheConcurrencyStrategy;
import javax.persistence.*;
@Entity
@Table(name="testdata")
@Cache(usage=CacheConcurrencyStrategy.READ_WRITE, region="regionforusers")
public class User
{
  @Id
  @GeneratedValue(strategy=GenerationType.IDENTITY)
  private int id;
  //
  private String name;
  // + getters/setters
}


Application code :
Code:
      EntityManager manager=factory.createEntityManager();
      qr=manager.createQuery("select u from User u where u.id="+id);
      qr=manager.createQuery("select u from User u where u.id="+id);


=> both queries are sent to mysql (shown in mysql server log)

I tried to add
Code:
qr.setHint("org.hibernate.cacheable",true);
but it did not change.
I tried to add a minimal ehcache.xml but it did not change.
I don't understand why there is no caching, and why there is absolutely no error in logs...

The small sample is here with full code and IntelliJ Project: https://www.5flow.com/tmp/ehcache-2017-10-12.zip
Thanks.


Top
 Profile  
 
 Post subject: Re: using ehcache 3 in tomcat 8.5/hibernate 5.2
PostPosted: Fri Oct 13, 2017 9:26 am 
Hibernate Team
Hibernate Team

Joined: Thu Sep 11, 2014 2:50 am
Posts: 1628
Location: Romania
As I explained in this article, you need to set the following property as well:

Code:
<property name="hibernate.cache.use_query_cache" value="true"/>


And, you need to enable the query cache for every query as follows:

Code:
qr.setHint("org.hibernate.cacheable",true);


Otherwise, it will not work.


Top
 Profile  
 
 Post subject: Re: Hibernate Query Cache does not work with JCache and Ehcache
PostPosted: Fri Oct 13, 2017 11:43 am 
Newbie

Joined: Thu Oct 12, 2017 8:41 am
Posts: 8
Hi vlad, thanks for your answer.
As you can see it in my topic text, I did both what you suggest, and it still does not work (see the downloadable full sample project also).
Thanks


Top
 Profile  
 
 Post subject: Re: Hibernate Query Cache does not work with JCache and Ehcache
PostPosted: Fri Oct 13, 2017 2:22 pm 
Hibernate Team
Hibernate Team

Joined: Thu Sep 11, 2014 2:50 am
Posts: 1628
Location: Romania
How do you know it does not work? Did you activate the SQL log?

Check out this article For more info about the best way to log JDBC statements:

https://vladmihalcea.com/the-best-way-t ... tatements/


Top
 Profile  
 
 Post subject: Re: Hibernate Query Cache does not work with JCache and Ehcache
PostPosted: Sat Oct 14, 2017 4:26 pm 
Newbie

Joined: Thu Oct 12, 2017 8:41 am
Posts: 8
Hello vlad

I did not activate Hibernate sql Logging in persistence.xml (<property name="hibernate.show_sql" value="false"/>) because as far as I understand, it displays sql request even if the request is not sent to mysql when data comes from the cache. I did not activate sql logging in context.xml/<Resource> database url (profileSQL=true) because it displays huge stack trace not really readable.

I activated mysql logging directly in mysql : (set global general_log='on') which shows exactly all real requests received in the database.

My 2 last search in code :

Code:
      qr=manager.createQuery("select u from User u where u.id="+id);
      qr.setHint("org.hibernate.cacheable",true);
      users2=(List<User>) qr.getResultList();
      firstuser=users2.get(0);
      qr=manager.createQuery("select u from User u where u.id="+id);
      qr.setHint("org.hibernate.cacheable",true);
      users2=(List<User>) qr.getResultList();
      firstuser=users2.get(0);


Produces this log in Mysql :

Code:
2017-10-14T20:23:23.049164Z     390 Query   select user0_.id as id1_0_, user0_.name as name2_0_ from testdata user0_ where user0_.id=1
2017-10-14T20:23:23.051631Z     390 Query   select user0_.id as id1_0_, user0_.name as name2_0_ from testdata user0_ where user0_.id=1


Which means that Mysql received exactly twice the same request while the second should be cached.
Thanks


Top
 Profile  
 
 Post subject: Re: Hibernate Query Cache does not work with JCache and Ehcache
PostPosted: Sun Oct 15, 2017 1:49 am 
Hibernate Team
Hibernate Team

Joined: Thu Sep 11, 2014 2:50 am
Posts: 1628
Location: Romania
I have a test on GitHub which proves that the Query Cache works just fine. Fork my repository and debug it along with your code and see where they diverge.

Also, I'm using the Ehcache directly not through JCache:

Code:
properties.put("hibernate.cache.region.factory_class", "org.hibernate.cache.ehcache.EhCacheRegionFactory");


Although, I doubt it's because of that.

They way you concatenate Strings when building the SQL query is also wrong:

Code:
qr=manager.createQuery("select u from User u where u.id="+id);


You should never do that because you can risk SQL Injection attacks.


Top
 Profile  
 
 Post subject: Re: Hibernate Query Cache does not work with JCache and Ehcache
PostPosted: Mon Oct 16, 2017 1:41 am 
Newbie

Joined: Thu Oct 12, 2017 8:41 am
Posts: 8
Hello vlad

Don't worry about sql injection, this is only a sample, in my application I always use ":id" parameters

I tried to replace org.hibernate.cache.jcache.JCacheRegionFactory by org.hibernate.cache.ehcache.EhCacheRegionFactory but this class is not provided in libraries I included in my project (see my first post) :

Caused by: org.hibernate.boot.registry.selector.spi.StrategySelectionException: Unable to resolve name [org.hibernate.cache.ehcache.EhCacheRegionFactory] as strategy [org.hibernate.cache.spi.RegionFactory]

There is a maven library org.hibernate:hibernate-ehcache:5.2.11.Final which contains this class, but it uses ehcache 2.10 instead of 3.4 , an bit old no ! I tried anyway with this one, the application compiles correctly now, but the sql requests are sent twice to Mysql again, there is no 2nd level cache activated from my point of view.

I downloaded your sample on GitHub, but could not make it run, the class itself does not work alone, and the full project is very complex, I could not find the way to run the cache test correctly. (many errors that I'm not able to understand). By the way your sample use ehcache version 2, not 3. : <ehcache.version>2.6.9</ehcache.version>

I have no doubt that EhCache 2nd level cache works perfectly with Hibernate of course ! All I want is to make it work in my little sample.

Is there any chance that someone download the sample at https://www.5flow.com/tmp/ehcache-2017-10-12.zip and tell me what's wrong ? (it has only one class, with one little test, very few dependencies and can be opened and run directly in intellij in seconds)

Thanks a lot.


Top
 Profile  
 
 Post subject: Re: Hibernate Query Cache does not work with JCache and Ehcache
PostPosted: Mon Oct 16, 2017 4:10 am 
Hibernate Team
Hibernate Team

Joined: Thu Sep 11, 2014 2:50 am
Posts: 1628
Location: Romania
Quote:
Is there any chance that someone download the sample at https://www.5flow.com/tmp/ehcache-2017-10-12.zip and tell me what's wrong ? (it has only one class, with one little test, very few dependencies and can be opened and run directly in intellij in seconds)


Your project does not feature Maven so it takes way too much time to configure it, and it features no JUnit tests to rapidly figure out what's wrong.

What you can do is to isolate the data access code using the Hibernate unit test templates and figure out where you did it wrong.

Cheers.


Top
 Profile  
 
 Post subject: Re: Hibernate Query Cache does not work with JCache and Ehcache
PostPosted: Mon Oct 16, 2017 9:52 am 
Newbie

Joined: Thu Oct 12, 2017 8:41 am
Posts: 8
Hello vlad

I downloaded the hibernate unit test template which was very useful.
I wrote a little unit test with 2 identical queries. I made also exactly the same program within tomcat 8.5.

Both programs use (quite) exactly the same source code, exactly the same persistence.xml, the same jars with same versions, the same database driver, the same database schema and the same entity bean.

When running in junit, ehcache is working and the second request is not sent to mysql
When running in tomcat, the second request is sent to mysql, ehcache is not activated.

Can you imagine a reason for that ?
Both projects are available here : https://www.5flow.com/tmp/ehcache-2017-19-16.zip

Should I go to tomcat users mailing list ?
Thanks


Top
 Profile  
 
 Post subject: Re: Hibernate Query Cache does not work with JCache and Ehcache
PostPosted: Mon Oct 16, 2017 10:07 am 
Hibernate Team
Hibernate Team

Joined: Thu Sep 11, 2014 2:50 am
Posts: 1628
Location: Romania
It's good that you have both tests in place now. What you can do is debug both of them to see why the Unit Test works while the web-app does not.

I can only suspect that the properties are not loaded or they are loaded from a different place or something like that.

It makes no sense to ask on the Tomcat forum, it's not like this is a Tomcat issue. It's just your particular application settings that are causing the problem.

Therefore, just debug it and see why it does not work. You will find a way where they diverge.


Top
 Profile  
 
 Post subject: Re: Hibernate Query Cache does not work with JCache and Ehcache
PostPosted: Mon Oct 16, 2017 11:14 am 
Newbie

Joined: Thu Oct 12, 2017 8:41 am
Posts: 8
The properties seems all right to me. But I think I found...thanks to your suggestion.

I entered "qr.getResultList()", IntelliJ decompiles for me the .class files... deep inside unknown world !!!
In Tomcat, the queryCache is correctly loaded in hibernate.loader.Loader.listUsingQueryCache() , just like in junit. But I found that there was a difference at UpdateTimestampsCache.isUpToDate() ! So I had the idea that in junit, there are 2 entity managers created, one for each test, while in tomcat there is only one. After some tests I found the following conclusion :

In tomcat AND in junit, this code:

Code:
         EntityManager entityManager=factory.createEntityManager();
         // open transaction
         entityManager.getTransaction().begin();
         // create user
         User user=new User();
         user.setName("a");
         entityManager.persist(user);
         // commit transaction
         entityManager.getTransaction().commit();
         // finish
         entityManager.close();
         //
         //
         entityManager=factory.createEntityManager();
         // request first
         Query qr=entityManager.createQuery("select u from User u");
         qr.setHint("org.hibernate.cacheable",true);
         List<User> users2=(List<User>)qr.getResultList();
         User firstuser=users2.get(0);
         // request second
         qr=entityManager.createQuery("select u from User u");
         qr.setHint("org.hibernate.cacheable",true);
         users2=(List<User>)qr.getResultList();
         firstuser=users2.get(0);
         // finish
         entityManager.close();


produces the following mysql requests :

Code:
2017-10-16T15:02:11.851499Z     677 Query   SET autocommit=0
2017-10-16T15:02:11.851791Z     677 Query   SET autocommit=0
2017-10-16T15:02:11.852733Z     677 Query   insert into testdata (name) values ('a')
2017-10-16T15:02:11.854003Z     677 Query   commit
2017-10-16T15:02:11.856762Z     677 Query   SET autocommit=1
2017-10-16T15:02:11.858292Z     677 Query   SET autocommit=0
2017-10-16T15:02:11.858716Z     677 Query   select user0_.id as id1_0_, user0_.name as name2_0_ from testdata user0_
2017-10-16T15:02:11.885065Z     677 Query   SET autocommit=1


while this code (commenting the close/create in the middle):

Code:
         EntityManager entityManager=factory.createEntityManager();
         // open transaction
         entityManager.getTransaction().begin();
         // create user
         User user=new User();
         user.setName("a");
         entityManager.persist(user);
         // commit transaction
         entityManager.getTransaction().commit();
         // finish
         //entityManager.close();
         //
         //
         //entityManager=factory.createEntityManager();
         // request first
         Query qr=entityManager.createQuery("select u from User u");
         qr.setHint("org.hibernate.cacheable",true);
         List<User> users2=(List<User>)qr.getResultList();
         User firstuser=users2.get(0);
         // request second
         qr=entityManager.createQuery("select u from User u");
         qr.setHint("org.hibernate.cacheable",true);
         users2=(List<User>)qr.getResultList();
         firstuser=users2.get(0);
         // finish
         entityManager.close();


produces the follwing queries in mysql :

Code:
2017-10-16T15:03:26.750906Z     678 Query   SET autocommit=0
2017-10-16T15:03:26.751182Z     678 Query   SET autocommit=0
2017-10-16T15:03:26.752156Z     678 Query   insert into testdata (name) values ('a')
2017-10-16T15:03:26.753986Z     678 Query   commit
2017-10-16T15:03:26.754612Z     678 Query   SET autocommit=1
2017-10-16T15:03:26.756820Z     678 Query   SET autocommit=0
2017-10-16T15:03:26.757320Z     678 Query   select user0_.id as id1_0_, user0_.name as name2_0_ from testdata user0_
2017-10-16T15:03:26.803988Z     678 Query   SET autocommit=1
2017-10-16T15:03:26.805503Z     678 Query   SET autocommit=0
2017-10-16T15:03:26.806285Z     678 Query   select user0_.id as id1_0_, user0_.name as name2_0_ from testdata user0_
2017-10-16T15:03:26.816678Z     678 Query   SET autocommit=1


I don't understand the reason for that. Why should I close the entity manager between the add and the query ? As long as the commit is done I should be able to use the same entity manager for all my queries ? (in one http request).
Here the code that demonstrated double request to mysql with junit template : https://www.5flow.com/tmp/ehcache-2017-10-16.2.zip

Thanks for any explanation...


Top
 Profile  
 
 Post subject: Re: Hibernate Query Cache does not work with JCache and Ehcache
PostPosted: Mon Oct 16, 2017 1:31 pm 
Hibernate Team
Hibernate Team

Joined: Thu Sep 11, 2014 2:50 am
Posts: 1628
Location: Romania
Just use Spring Transaction Manager and inject the Persistence Context and let Spring take care of EntityManager and Transaction lifecycle.

It makes no sense to do it manually as you are doing it now. You rarely need to bootstrap Hibernate natively. Just use Spring or Java EE and you won't have to deal with all these issues.


Top
 Profile  
 
 Post subject: Re: Hibernate Query Cache does not work with JCache and Ehcache
PostPosted: Tue Oct 17, 2017 3:17 am 
Newbie

Joined: Thu Oct 12, 2017 8:41 am
Posts: 8
Sorry but we decided not to use Spring. Spring is a great tool and help developers in many cases, but from our point of view, and for the current projet, it is too difficult to learn and understand, and it seems that we don't really need it. Maybe we're wrong, but until now we could not find anything that changed our choice.

If what I found here is a normal behaviour with Hibernate/EhCache, I'm not sure we'll use Hibernate either. I expect a JPA implementation to be simple to use and simple to configure, like I used to do in a past projects with Caucho's Resin that provided EclipseLink.

If there is no workaround, I'll stop now my investigation on Hibernate/EhCache. If there is one, please give me a clue.
Thanks


Top
 Profile  
 
 Post subject: Re: Hibernate Query Cache does not work with JCache and Ehcache
PostPosted: Tue Oct 17, 2017 3:23 am 
Hibernate Team
Hibernate Team

Joined: Thu Sep 11, 2014 2:50 am
Posts: 1628
Location: Romania
Quote:
Sorry but we decided not to use Spring. Spring is a great tool and help developers in many cases, but from our point of view, and for the current project, it is too difficult to learn and understand, and it seems that we don't really need it. Maybe we're wrong, but until now we could not find anything that changed our choice.


Spring is anything but difficult to learn, and it takes care of all the bootstrapping logic you are struggling with now.

Quote:
If what I found here is a normal behavior with Hibernate/EhCache, I'm not sure we'll use Hibernate either. I expect a JPA implementation to be simple to use and simple to configure like I used to do in past projects with Caucho's Resin that provided EclipseLink.


As you already experienced when doing the Unit Tests, as long as the configuration is properly done, you will have no issue. However, your manual configuration is wrong.

Quote:
If there is no workaround, I'll stop now my investigation on Hibernate/EhCache. If there is one, please give me a clue.


This is not related to Hibernate. Most likely it's a web app config issue. Even if you didn't use Hibernate/EhCache, you'd still have issues with other frameworks if the problem is related to the web app config.


Top
 Profile  
 
 Post subject: Re: Hibernate Query Cache does not work with JCache and Ehcache
PostPosted: Tue Oct 17, 2017 4:04 am 
Newbie

Joined: Thu Oct 12, 2017 8:41 am
Posts: 8
Well, I'm probably too ignorant or too old :) to understand Spring. Its configuration seemed very difficult to me, from the readings and from trying tutorials and samples (from spring site and others) that simply did not work at all.

From my point of view, if there is a configuration problem, there must be a configuration somewhere to fix that should be documented on ehcache site or hibernate site, and I could not find that. I did exactly what tutorials about Hibernate/EhCache suggested, and found no other information on how to configure more for ehcache in hibernate. It was actually already difficult to find configuration information for latest versions of hibernate and ehcache, because most forums talked about old versions.

I wish to thank you very much for your help, I appreciated the time you spent helping me.


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 16 posts ]  Go to page 1, 2  Next

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.