Hibernate second-level cache.
This commit is contained in:
		
							parent
							
								
									440e247176
								
							
						
					
					
						commit
						8a03456386
					
				| @ -29,6 +29,11 @@ | ||||
|             <artifactId>hibernate-entitymanager</artifactId> | ||||
|             <version>${hibernate.version}</version> | ||||
|         </dependency> | ||||
|         <dependency> | ||||
|             <groupId>org.hibernate</groupId> | ||||
|             <artifactId>hibernate-ehcache</artifactId> | ||||
|             <version>${hibernate.version}</version> | ||||
|         </dependency> | ||||
|         <dependency> | ||||
|             <groupId>xml-apis</groupId> | ||||
|             <artifactId>xml-apis</artifactId> | ||||
| @ -50,6 +55,11 @@ | ||||
|             <artifactId>spring-data-jpa</artifactId> | ||||
|             <version>${spring-data-jpa.version}</version> | ||||
|         </dependency> | ||||
|         <dependency> | ||||
|             <groupId>com.h2database</groupId> | ||||
|             <artifactId>h2</artifactId> | ||||
|             <version>${h2.version}</version> | ||||
|         </dependency> | ||||
| 
 | ||||
|         <!-- validation --> | ||||
| 
 | ||||
| @ -186,6 +196,7 @@ | ||||
|         <hibernate.version>4.3.11.Final</hibernate.version> | ||||
|         <mysql-connector-java.version>5.1.38</mysql-connector-java.version> | ||||
|         <spring-data-jpa.version>1.8.2.RELEASE</spring-data-jpa.version> | ||||
|         <h2.version>1.4.192</h2.version> | ||||
| 
 | ||||
|         <!-- logging --> | ||||
|         <org.slf4j.version>1.7.13</org.slf4j.version> | ||||
|  | ||||
| @ -78,6 +78,8 @@ public class PersistenceJPAConfig { | ||||
|         final Properties hibernateProperties = new Properties(); | ||||
|         hibernateProperties.setProperty("hibernate.hbm2ddl.auto", env.getProperty("hibernate.hbm2ddl.auto")); | ||||
|         hibernateProperties.setProperty("hibernate.dialect", env.getProperty("hibernate.dialect")); | ||||
|         hibernateProperties.setProperty("hibernate.cache.use_second_level_cache", env.getProperty("hibernate.cache.use_second_level_cache")); | ||||
|         hibernateProperties.setProperty("hibernate.cache.use_query_cache", env.getProperty("hibernate.cache.use_query_cache")); | ||||
|         // hibernateProperties.setProperty("hibernate.globally_quoted_identifiers", "true"); | ||||
|         return hibernateProperties; | ||||
|     } | ||||
|  | ||||
| @ -0,0 +1,84 @@ | ||||
| package org.baeldung.config; | ||||
| 
 | ||||
| import com.google.common.base.Preconditions; | ||||
| import org.springframework.beans.factory.annotation.Autowired; | ||||
| import org.springframework.context.annotation.Bean; | ||||
| import org.springframework.context.annotation.ComponentScan; | ||||
| import org.springframework.context.annotation.Configuration; | ||||
| import org.springframework.context.annotation.PropertySource; | ||||
| import org.springframework.core.env.Environment; | ||||
| import org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor; | ||||
| import org.springframework.data.jpa.repository.config.EnableJpaRepositories; | ||||
| import org.springframework.jdbc.datasource.DriverManagerDataSource; | ||||
| import org.springframework.orm.jpa.JpaTransactionManager; | ||||
| import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; | ||||
| import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter; | ||||
| import org.springframework.transaction.PlatformTransactionManager; | ||||
| import org.springframework.transaction.annotation.EnableTransactionManagement; | ||||
| 
 | ||||
| import javax.persistence.EntityManagerFactory; | ||||
| import javax.sql.DataSource; | ||||
| import java.util.Properties; | ||||
| 
 | ||||
| @Configuration | ||||
| @EnableTransactionManagement | ||||
| @PropertySource({ "classpath:persistence-h2.properties" }) | ||||
| @ComponentScan({ "org.baeldung.persistence" }) | ||||
| @EnableJpaRepositories(basePackages = "org.baeldung.persistence.dao") | ||||
| public class PersistenceJPAConfigL2Cache { | ||||
| 
 | ||||
|     @Autowired | ||||
|     private Environment env; | ||||
| 
 | ||||
|     public PersistenceJPAConfigL2Cache() { | ||||
|         super(); | ||||
|     } | ||||
| 
 | ||||
|     // beans | ||||
| 
 | ||||
|     @Bean | ||||
|     public LocalContainerEntityManagerFactoryBean entityManagerFactory() { | ||||
|         final LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean(); | ||||
|         em.setDataSource(dataSource()); | ||||
|         em.setPackagesToScan(new String[] { "org.baeldung.persistence.model" }); | ||||
| 
 | ||||
|         final HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter(); | ||||
|         em.setJpaVendorAdapter(vendorAdapter); | ||||
|         em.setJpaProperties(additionalProperties()); | ||||
| 
 | ||||
|         return em; | ||||
|     } | ||||
| 
 | ||||
|     @Bean | ||||
|     public DataSource dataSource() { | ||||
|         final DriverManagerDataSource dataSource = new DriverManagerDataSource(); | ||||
|         dataSource.setDriverClassName(Preconditions.checkNotNull(env.getProperty("jdbc.driverClassName"))); | ||||
|         dataSource.setUrl(Preconditions.checkNotNull(env.getProperty("jdbc.url"))); | ||||
|         dataSource.setUsername(Preconditions.checkNotNull(env.getProperty("jdbc.user"))); | ||||
| 
 | ||||
|         return dataSource; | ||||
|     } | ||||
| 
 | ||||
|     @Bean | ||||
|     public PlatformTransactionManager transactionManager(final EntityManagerFactory emf) { | ||||
|         final JpaTransactionManager transactionManager = new JpaTransactionManager(); | ||||
|         transactionManager.setEntityManagerFactory(emf); | ||||
|         return transactionManager; | ||||
|     } | ||||
| 
 | ||||
|     @Bean | ||||
|     public PersistenceExceptionTranslationPostProcessor exceptionTranslation() { | ||||
|         return new PersistenceExceptionTranslationPostProcessor(); | ||||
|     } | ||||
| 
 | ||||
|     final Properties additionalProperties() { | ||||
|         final Properties hibernateProperties = new Properties(); | ||||
|         hibernateProperties.setProperty("hibernate.hbm2ddl.auto", env.getProperty("hibernate.hbm2ddl.auto")); | ||||
|         hibernateProperties.setProperty("hibernate.dialect", env.getProperty("hibernate.dialect")); | ||||
|         hibernateProperties.setProperty("hibernate.cache.use_second_level_cache", env.getProperty("hibernate.cache.use_second_level_cache")); | ||||
|         hibernateProperties.setProperty("hibernate.cache.use_query_cache", env.getProperty("hibernate.cache.use_query_cache")); | ||||
|         hibernateProperties.setProperty("hibernate.cache.region.factory_class", env.getProperty("hibernate.cache.region.factory_class")); | ||||
|         return hibernateProperties; | ||||
|     } | ||||
| 
 | ||||
| } | ||||
| @ -1,17 +1,13 @@ | ||||
| package org.baeldung.persistence.model; | ||||
| 
 | ||||
| import org.hibernate.annotations.CacheConcurrencyStrategy; | ||||
| 
 | ||||
| import javax.persistence.*; | ||||
| import java.io.Serializable; | ||||
| 
 | ||||
| import javax.persistence.Column; | ||||
| import javax.persistence.Entity; | ||||
| import javax.persistence.FetchType; | ||||
| import javax.persistence.GeneratedValue; | ||||
| import javax.persistence.GenerationType; | ||||
| import javax.persistence.Id; | ||||
| import javax.persistence.JoinColumn; | ||||
| import javax.persistence.ManyToOne; | ||||
| 
 | ||||
| @Entity | ||||
| @Cacheable | ||||
| @org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.READ_WRITE) | ||||
| public class Foo implements Serializable { | ||||
| 
 | ||||
|     private static final long serialVersionUID = 1L; | ||||
|  | ||||
| @ -21,6 +21,8 @@ | ||||
|             <props> | ||||
|                 <prop key="hibernate.hbm2ddl.auto">${hibernate.hbm2ddl.auto}</prop> | ||||
|                 <prop key="hibernate.dialect">${hibernate.dialect}</prop> | ||||
|                 <prop key="hibernate.cache.use_second_level_cache">${hibernate.cache.use_second_level_cache}</prop> | ||||
|                 <prop key="hibernate.cache.use_query_cache">${hibernate.cache.use_query_cache}</prop> | ||||
|             </props> | ||||
|         </property> | ||||
|     </bean> | ||||
|  | ||||
							
								
								
									
										13
									
								
								spring-jpa/src/main/resources/persistence-h2.properties
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								spring-jpa/src/main/resources/persistence-h2.properties
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,13 @@ | ||||
| # jdbc.X | ||||
| jdbc.driverClassName=org.h2.Driver | ||||
| jdbc.url=jdbc:h2:mem:db;DB_CLOSE_DELAY=-1 | ||||
| jdbc.user=sa | ||||
| # jdbc.pass= | ||||
| 
 | ||||
| # hibernate.X | ||||
| hibernate.dialect=org.hibernate.dialect.H2Dialect | ||||
| hibernate.show_sql=false | ||||
| hibernate.hbm2ddl.auto=create-drop | ||||
| hibernate.cache.use_second_level_cache=true | ||||
| hibernate.cache.use_query_cache=true | ||||
| hibernate.cache.region.factory_class=org.hibernate.cache.ehcache.EhCacheRegionFactory | ||||
| @ -9,3 +9,5 @@ jdbc.pass=tutorialmy5ql | ||||
| hibernate.dialect=org.hibernate.dialect.MySQL5Dialect | ||||
| hibernate.show_sql=false | ||||
| hibernate.hbm2ddl.auto=create-drop | ||||
| hibernate.cache.use_second_level_cache=false | ||||
| hibernate.cache.use_query_cache=false | ||||
| @ -8,3 +8,5 @@ jdbc.pass=tutorialmy5ql | ||||
| hibernate.dialect=org.hibernate.dialect.MySQL5Dialect | ||||
| hibernate.show_sql=false | ||||
| hibernate.hbm2ddl.auto=create-drop | ||||
| hibernate.cache.use_second_level_cache=false | ||||
| hibernate.cache.use_query_cache=false | ||||
| @ -10,6 +10,8 @@ | ||||
|         <property name="javax.persistence.ddl-generation" value="drop-and-create-tables"/> | ||||
|         <property name="javax.persistence.logging.level" value="INFO"/> | ||||
|         <property name = "hibernate.show_sql" value = "true" /> | ||||
|         <property name = "hibernate.cache.use_second_level_cache" value = "false" /> | ||||
|         <property name = "hibernate.cache.use_query_cache" value = "false" /> | ||||
|       </properties> | ||||
| 		 | ||||
| 	</persistence-unit> | ||||
|  | ||||
| @ -0,0 +1,84 @@ | ||||
| package org.baeldung.persistence.service; | ||||
| 
 | ||||
| import net.sf.ehcache.CacheManager; | ||||
| import org.baeldung.config.PersistenceJPAConfigL2Cache; | ||||
| import org.baeldung.persistence.model.Bar; | ||||
| import org.baeldung.persistence.model.Foo; | ||||
| import org.junit.Before; | ||||
| import org.junit.Test; | ||||
| import org.junit.runner.RunWith; | ||||
| import org.springframework.beans.factory.annotation.Autowired; | ||||
| import org.springframework.test.context.ContextConfiguration; | ||||
| import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; | ||||
| import org.springframework.test.context.support.AnnotationConfigContextLoader; | ||||
| import org.springframework.transaction.PlatformTransactionManager; | ||||
| import org.springframework.transaction.support.TransactionTemplate; | ||||
| 
 | ||||
| import javax.persistence.EntityManager; | ||||
| import javax.persistence.PersistenceContext; | ||||
| import javax.persistence.Query; | ||||
| 
 | ||||
| import static org.apache.commons.lang3.RandomStringUtils.randomAlphabetic; | ||||
| import static org.hamcrest.Matchers.greaterThan; | ||||
| import static org.junit.Assert.assertThat; | ||||
| 
 | ||||
| @RunWith(SpringJUnit4ClassRunner.class) | ||||
| @ContextConfiguration(classes = { PersistenceJPAConfigL2Cache.class }, loader = AnnotationConfigContextLoader.class) | ||||
| public class SecondLevelCacheIntegrationTest { | ||||
| 
 | ||||
|     @PersistenceContext | ||||
|     private EntityManager entityManager; | ||||
|     @Autowired | ||||
|     private FooService fooService; | ||||
|     @Autowired | ||||
|     private PlatformTransactionManager platformTransactionManager; | ||||
| 
 | ||||
|     @Before | ||||
|     public final void before() { | ||||
|         entityManager.getEntityManagerFactory().getCache().evictAll(); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     public final void givenEntityIsLoaded_thenItIsCached() { | ||||
|         final Foo foo = new Foo(randomAlphabetic(6)); | ||||
|         fooService.create(foo); | ||||
|         fooService.findOne(foo.getId()); | ||||
|         final int size = CacheManager.ALL_CACHE_MANAGERS.get(0) | ||||
|                 .getCache("org.baeldung.persistence.model.Foo").getSize(); | ||||
|         assertThat(size, greaterThan(0)); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     public final void givenBarIsUpdatedInNativeQuery_thenFoosAreNotEvicted() { | ||||
|         final Foo foo = new Foo(randomAlphabetic(6)); | ||||
|         fooService.create(foo); | ||||
|         fooService.findOne(foo.getId()); | ||||
| 
 | ||||
|         new TransactionTemplate(platformTransactionManager).execute(status -> { | ||||
|             final Bar bar = new Bar(randomAlphabetic(6)); | ||||
|             entityManager.persist(bar); | ||||
|             final Query nativeQuery = entityManager.createNativeQuery("update BAR set NAME = :updatedName where ID = :id"); | ||||
|             nativeQuery.setParameter("updatedName", "newName"); | ||||
|             nativeQuery.setParameter("id", bar.getId()); | ||||
|             nativeQuery.unwrap(org.hibernate.SQLQuery.class).addSynchronizedEntityClass(Bar.class); | ||||
|             return nativeQuery.executeUpdate(); | ||||
|         }); | ||||
| 
 | ||||
|         final int size = CacheManager.ALL_CACHE_MANAGERS.get(0) | ||||
|                 .getCache("org.baeldung.persistence.model.Foo").getSize(); | ||||
|         assertThat(size, greaterThan(0)); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     public final void givenCacheableQueryIsExecuted_thenItIsCached() { | ||||
|         new TransactionTemplate(platformTransactionManager).execute(status -> { | ||||
|             return entityManager.createQuery("select f from Foo f") | ||||
|                     .setHint("org.hibernate.cacheable", true) | ||||
|                     .getResultList(); | ||||
|         }); | ||||
| 
 | ||||
|         final int size = CacheManager.ALL_CACHE_MANAGERS.get(0) | ||||
|                 .getCache("org.hibernate.cache.internal.StandardQueryCache").getSize(); | ||||
|         assertThat(size, greaterThan(0)); | ||||
|     } | ||||
| } | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user