Just try to use 2nd level cache with WildFly and Hibernate
TweetPosted on Wednesday Feb 19, 2014 at 05:30PM in Technology
Just playing with 2nd level cache that mentioned at [1]. it is a good tutorial so may we only need to refer [1], and this is my notes and logs only.
Environment
- WildFly 8.0.0.Final (Hibernate 4.3.1)
- Maven 3.1.1
- Oracle JDK7u51
- OS X 10.9.1
Run Maven to get the sample project
kyle-no-MacBook:l2cache kyle$ mvn archetype:generate \ > -DarchetypeArtifactId=jboss-javaee6-webapp-archetype \ > -DarchetypeGroupId=org.jboss.spec.archetypes \ > -DarchetypeVersion=7.1.2.Final \ > -DgroupId=de.consol.research \ > -DartifactId=infinispan-jpa-example \ > -Dversion=1.0-SNAPSHOT \ > -Dname="Infinispan JPA Example" \ > -DarchetypeCatalog=http://search.maven.org/remotecontent?filepath=archetype-catalog.xml \ > -DinteractiveMode=false Picked up _JAVA_OPTIONS: -Dfile.encoding=UTF-8 [INFO] Scanning for projects... Downloading: http://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven-install-plugin/2.4/maven-install-plugin-2.4.pom Downloaded: http://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven-install-plugin/2.4/maven-install-plugin-2.4.pom (7 KB at 5.4 KB/sec) Downloading: http://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven-deploy-plugin/2.7/maven-deploy-plugin-2.7.pom Downloaded: http://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven-deploy-plugin/2.7/maven-deploy-plugin-2.7.pom (6 KB at 20.5 KB/sec) Downloading: http://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven-site-plugin/3.3/maven-site-plugin-3.3.pom Downloaded: http://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven-site-plugin/3.3/maven-site-plugin-3.3.pom (21 KB at 51.1 KB/sec) Downloading: http://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven-site-plugin/3.3/maven-site-plugin-3.3.jar Downloaded: http://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven-site-plugin/3.3/maven-site-plugin-3.3.jar (122 KB at 180.7 KB/sec) Downloading: http://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven-antrun-plugin/1.3/maven-antrun-plugin-1.3.pom Downloaded: http://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven-antrun-plugin/1.3/maven-antrun-plugin-1.3.pom (5 KB at 17.0 KB/sec) Downloading: http://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven-antrun-plugin/1.3/maven-antrun-plugin-1.3.jar Downloaded: http://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven-antrun-plugin/1.3/maven-antrun-plugin-1.3.jar (24 KB at 84.3 KB/sec) Downloading: http://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven-assembly-plugin/2.2-beta-5/maven-assembly-plugin-2.2-beta-5.pom Downloaded: http://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven-assembly-plugin/2.2-beta-5/maven-assembly-plugin-2.2-beta-5.pom (15 KB at 55.4 KB/sec) Downloading: http://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven-plugins/16/maven-plugins-16.pom Downloaded: http://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven-plugins/16/maven-plugins-16.pom (13 KB at 47.0 KB/sec) Downloading: http://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven-assembly-plugin/2.2-beta-5/maven-assembly-plugin-2.2-beta-5.jar Downloaded: http://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven-assembly-plugin/2.2-beta-5/maven-assembly-plugin-2.2-beta-5.jar (204 KB at 357.8 KB/sec) Downloading: http://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven-dependency-plugin/2.8/maven-dependency-plugin-2.8.pom Downloaded: http://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven-dependency-plugin/2.8/maven-dependency-plugin-2.8.pom (12 KB at 41.7 KB/sec) Downloading: http://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven-dependency-plugin/2.8/maven-dependency-plugin-2.8.jar Downloaded: http://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven-dependency-plugin/2.8/maven-dependency-plugin-2.8.jar (150 KB at 274.5 KB/sec) [INFO] [INFO] ------------------------------------------------------------------------ [INFO] Building Maven Stub Project (No POM) 1 [INFO] ------------------------------------------------------------------------ [INFO] [INFO] >>> maven-archetype-plugin:2.2:generate (default-cli) @ standalone-pom >>> [INFO] [INFO] <<< maven-archetype-plugin:2.2:generate (default-cli) @ standalone-pom <<< [INFO] [INFO] --- maven-archetype-plugin:2.2:generate (default-cli) @ standalone-pom --- Downloading: http://repo.maven.apache.org/maven2/org/apache/maven/reporting/maven-reporting-api/2.0.8/maven-reporting-api-2.0.8.jar Downloading: http://repo.maven.apache.org/maven2/org/apache/maven/doxia/doxia-sink-api/1.0-alpha-9/doxia-sink-api-1.0-alpha-9.jar Downloading: http://repo.maven.apache.org/maven2/org/codehaus/plexus/plexus-interactivity-api/1.0-alpha-5/plexus-interactivity-api-1.0-alpha-5.jar Downloaded: http://repo.maven.apache.org/maven2/org/apache/maven/reporting/maven-reporting-api/2.0.8/maven-reporting-api-2.0.8.jar (10 KB at 28.5 KB/sec) Downloaded: http://repo.maven.apache.org/maven2/org/apache/maven/doxia/doxia-sink-api/1.0-alpha-9/doxia-sink-api-1.0-alpha-9.jar (10 KB at 19.8 KB/sec) Downloaded: http://repo.maven.apache.org/maven2/org/codehaus/plexus/plexus-interactivity-api/1.0-alpha-5/plexus-interactivity-api-1.0-alpha-5.jar (14 KB at 26.0 KB/sec) [INFO] Generating project in Batch mode [INFO] Archetype repository missing. Using the one from [org.jboss.spec.archetypes:jboss-javaee6-webapp-archetype:7.1.3.Final] found in catalog http://search.maven.org/remotecontent?filepath=archetype-catalog.xml Downloading: http://search.maven.org/org/jboss/spec/archetypes/jboss-javaee6-webapp-archetype/7.1.2.Final/jboss-javaee6-webapp-archetype-7.1.2.Final.jar Downloading: http://repo.maven.apache.org/maven2/org/jboss/spec/archetypes/jboss-javaee6-webapp-archetype/7.1.2.Final/jboss-javaee6-webapp-archetype-7.1.2.Final.jar Downloaded: http://repo.maven.apache.org/maven2/org/jboss/spec/archetypes/jboss-javaee6-webapp-archetype/7.1.2.Final/jboss-javaee6-webapp-archetype-7.1.2.Final.jar (96 KB at 88.0 KB/sec) Downloading: http://search.maven.org/org/jboss/spec/archetypes/jboss-javaee6-webapp-archetype/7.1.2.Final/jboss-javaee6-webapp-archetype-7.1.2.Final.pom Downloading: http://repo.maven.apache.org/maven2/org/jboss/spec/archetypes/jboss-javaee6-webapp-archetype/7.1.2.Final/jboss-javaee6-webapp-archetype-7.1.2.Final.pom Downloaded: http://repo.maven.apache.org/maven2/org/jboss/spec/archetypes/jboss-javaee6-webapp-archetype/7.1.2.Final/jboss-javaee6-webapp-archetype-7.1.2.Final.pom (3 KB at 5.5 KB/sec) [INFO] ---------------------------------------------------------------------------- [INFO] Using following parameters for creating project from Archetype: jboss-javaee6-webapp-archetype:7.1.2.Final [INFO] ---------------------------------------------------------------------------- [INFO] Parameter: groupId, Value: de.consol.research [INFO] Parameter: artifactId, Value: infinispan-jpa-example [INFO] Parameter: version, Value: 1.0-SNAPSHOT [INFO] Parameter: package, Value: de.consol.research [INFO] Parameter: packageInPathFormat, Value: de/consol/research [INFO] Parameter: package, Value: de.consol.research [INFO] Parameter: version, Value: 1.0-SNAPSHOT [INFO] Parameter: name, Value: Infinispan JPA Example [INFO] Parameter: groupId, Value: de.consol.research [INFO] Parameter: jboss-bom-enterprise-version, Value: 1.0.4.Final-redhat-1 [INFO] Parameter: artifactId, Value: infinispan-jpa-example [INFO] Parameter: enterprise, Value: false [INFO] project created from Archetype in dir: /Users/kyle/src/l2cache/infinispan-jpa-example [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ [INFO] Total time: 18.514s [INFO] Finished at: Wed Feb 19 17:26:26 JST 2014 [INFO] Final Memory: 14M/245M [INFO] ------------------------------------------------------------------------
Import the project to Eclipse
- File - Import - Existing Maven Projects
- It comes with no errors.
Make the application to use PostgreSQL
This is not necessary for everyone. It comes with internal H2 datasource definition in the application so we can just skip this work.
Create a database
jbatch=# create database infinispan owner kyle encoding 'UTF8' TEMPLATE template0; CREATE DATABASE jbatch=#
Define a data source
data-source add \ --name=InfinispanExampleDS \ --driver-name=postgresql \ --connection-url=jdbc:postgresql://localhost:5432/infinispan \ --jndi-name=java:jboss/datasources/infinispan-jpa-exampleDS \ --user-name=postgres \ --password=***
Delete datasource definition in WEB-INF
delete Deployed Resources/webapp/WEB-INF/infinispan-jpa-example-ds.xml
Deploy
I did it with Eclipse.
- Open Servers Window
- Right-click WildFly
- Add and remove
- Add infinispan-jpa-example
- Finish
Browse JSF page
- Browse here
- When we reload the page, every time it executes SELECT clause. like this:
17:46:37,631 DEBUG [org.hibernate.SQL] (default task-11) select member0_.id as id1_0_, member0_.email as email2_0_, member0_.name as name3_0_, member0_.phone_number as phone_nu4_0_ from Member member0_ order by member0_.name asc 17:46:39,055 DEBUG [org.hibernate.SQL] (default task-12) select member0_.id as id1_0_, member0_.email as email2_0_, member0_.name as name3_0_, member0_.phone_number as phone_nu4_0_ from Member member0_ order by member0_.name asc 17:49:13,527 DEBUG [org.hibernate.SQL] (default task-10) select member0_.id as id1_0_, member0_.email as email2_0_, member0_.name as name3_0_, member0_.phone_number as phone_nu4_0_ from Member member0_ order by member0_.name asc
- One test data is already registered when we browse the page.
Send GET request
kyle-no-MacBook:infinispan-jpa-example kyle$ curl http://localhost:8080/infinispan-jpa-example/rest/members/0 <?xml version="1.0" encoding="UTF-8" standalone="yes"?><member><email>john.smith@mailinator.com</email><id>0</id><name>John Smith</name><phoneNumber>2125551212</phoneNumber></member>kyle-no-MacBook:infinispan-jpa-example kyle$
It executes SQL for every request.
17:55:28,664 DEBUG [org.hibernate.SQL] (default task-6) select member0_.id as id1_0_0_, member0_.email as email2_0_0_, member0_.name as name3_0_0_, member0_.phone_number as phone_nu4_0_0_ from Member member0_ where member0_.id=? 17:55:28,665 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] (default task-6) binding parameter [1] as [BIGINT] - [0]
Modify persistence.xml to use l2-cache
<?xml version="1.0" encoding="UTF-8"?> <persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=" http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"> <persistence-unit name="primary"> <!-- If you are running in a production environment, add a managed data source, the example data source is just for development and testing! --> <jta-data-source>java:jboss/datasources/infinispan-jpa-exampleDS</jta-data-source> <shared-cache-mode>DISABLE_SELECTIVE</shared-cache-mode> <properties> <!-- Properties for Hibernate --> <property name="hibernate.hbm2ddl.auto" value="create-drop" /> <property name="hibernate.show_sql" value="false" /> <property name="hibernate.cache.use_second_level_cache" value="true"/> </properties> </persistence-unit> </persistence>
Send GET request again
- Now SQL is executed only once.
Browse JSF page again
- It still executes SQL every time I reload. why?
Make the application to allow to use l2-cache for queries
In reference to [2], we still have to modify some codes.
Modify persistence.xml
Add this property:
<property name="hibernate.cache.use_query_cache" value="true" />
Now it is:
<?xml version="1.0" encoding="UTF-8"?> <persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=" http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"> <persistence-unit name="primary"> <!-- If you are running in a production environment, add a managed data source, the example data source is just for development and testing! --> <jta-data-source>java:jboss/datasources/infinispan-jpa-exampleDS</jta-data-source> <shared-cache-mode>DISABLE_SELECTIVE</shared-cache-mode> <properties> <!-- Properties for Hibernate --> <property name="hibernate.hbm2ddl.auto" value="create-drop" /> <property name="hibernate.show_sql" value="false" /> <property name="hibernate.cache.use_second_level_cache" value="true"/> <property name="hibernate.cache.use_query_cache" value="true" /> </properties> </persistence-unit> </persistence>
Modify the code of JSF page
The query is executed in MemberListProducer#retrieveAllMembersOrderedByName():
@PostConstruct public void retrieveAllMembersOrderedByName() { CriteriaBuilder cb = em.getCriteriaBuilder(); CriteriaQuery<Member> criteria = cb.createQuery(Member.class); Root<Member> member = criteria.from(Member.class); // Swap criteria statements if you would like to try out type-safe criteria queries, a new // feature in JPA 2.0 // criteria.select(member).orderBy(cb.asc(member.get(Member_.name))); criteria.select(member).orderBy(cb.asc(member.get("name"))); members = em.createQuery(criteria).getResultList(); }
Add the code that invokes Query#setHint():
setHint("org.hibernate.cacheable", true)
Now the code is:
@PostConstruct public void retrieveAllMembersOrderedByName() { CriteriaBuilder cb = em.getCriteriaBuilder(); CriteriaQuery<Member> criteria = cb.createQuery(Member.class); Root<Member> member = criteria.from(Member.class); // Swap criteria statements if you would like to try out type-safe criteria queries, a new // feature in JPA 2.0 // criteria.select(member).orderBy(cb.asc(member.get(Member_.name))); criteria.select(member).orderBy(cb.asc(member.get("name"))); members = em.createQuery(criteria).setHint("org.hibernate.cacheable", true).getResultList(); }
Browse JSF page once again
- Now SQL is executed only once even I reloaded many times.
Remarks
- As default, 2nd level cache is disabled for queries.
- It seems enabled for operations like EntityManager#find() only.
- Every time queries need to set hint “org.hibernate.cacheable=true”.
- According to [3], it seems to there is a way to avoid to invoke annoying setHint() method for every queries.
- Seems to Query Hints are can define at when we declare Named Query.
- May I would try it later.
References
Tags: jpa