| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You under the Apache License, Version 2.0 |
| * (the "License"); you may not use this file except in compliance with |
| * the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package org.apache.ignite.cache.hibernate; |
| |
| import java.util.HashSet; |
| import java.util.Iterator; |
| import java.util.List; |
| import java.util.Set; |
| import javax.cache.Cache; |
| import javax.persistence.Cacheable; |
| import javax.persistence.GeneratedValue; |
| import javax.persistence.Id; |
| import org.apache.ignite.IgniteCache; |
| import org.apache.ignite.configuration.CacheConfiguration; |
| import org.apache.ignite.configuration.IgniteConfiguration; |
| import org.apache.ignite.internal.IgniteKernal; |
| import org.apache.ignite.internal.processors.cache.IgniteCacheProxy; |
| import org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi; |
| import org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder; |
| import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest; |
| import org.hibernate.Session; |
| import org.hibernate.SessionFactory; |
| import org.hibernate.Transaction; |
| import org.hibernate.annotations.CacheConcurrencyStrategy; |
| import org.hibernate.boot.registry.StandardServiceRegistryBuilder; |
| import org.hibernate.cache.spi.access.AccessType; |
| import org.hibernate.cfg.Configuration; |
| import org.junit.Test; |
| import static org.apache.ignite.cache.CacheAtomicityMode.ATOMIC; |
| import static org.apache.ignite.cache.CacheMode.PARTITIONED; |
| import static org.apache.ignite.cache.hibernate.HibernateAccessStrategyFactory.REGION_CACHE_PROPERTY; |
| import static org.hibernate.cfg.AvailableSettings.CACHE_REGION_FACTORY; |
| import static org.hibernate.cfg.AvailableSettings.GENERATE_STATISTICS; |
| import static org.hibernate.cfg.AvailableSettings.HBM2DDL_AUTO; |
| import static org.hibernate.cfg.AvailableSettings.RELEASE_CONNECTIONS; |
| import static org.hibernate.cfg.AvailableSettings.USE_QUERY_CACHE; |
| import static org.hibernate.cfg.AvailableSettings.USE_SECOND_LEVEL_CACHE; |
| |
| /** |
| * Tests Hibernate L2 cache configuration. |
| */ |
| public class HibernateL2CacheConfigurationSelfTest extends GridCommonAbstractTest { |
| /** */ |
| public static final String ENTITY1_NAME = Entity1.class.getName(); |
| |
| /** */ |
| public static final String ENTITY2_NAME = Entity2.class.getName(); |
| |
| /** */ |
| public static final String ENTITY3_NAME = Entity3.class.getName(); |
| |
| /** */ |
| public static final String ENTITY4_NAME = Entity4.class.getName(); |
| |
| /** */ |
| public static final String TIMESTAMP_CACHE = "org.hibernate.cache.spi.UpdateTimestampsCache"; |
| |
| /** */ |
| public static final String QUERY_CACHE = "org.hibernate.cache.internal.StandardQueryCache"; |
| |
| /** */ |
| public static final String CONNECTION_URL = "jdbc:h2:mem:example;DB_CLOSE_DELAY=-1"; |
| |
| /** {@inheritDoc} */ |
| @Override protected void beforeTestsStarted() throws Exception { |
| startGrid(0); |
| } |
| |
| /** {@inheritDoc} */ |
| @Override protected void afterTest() throws Exception { |
| for (IgniteCacheProxy<?, ?> cache : ((IgniteKernal)grid(0)).caches()) |
| cache.clear(); |
| } |
| |
| /** {@inheritDoc} */ |
| @Override protected IgniteConfiguration getConfiguration(String igniteInstanceName) throws Exception { |
| IgniteConfiguration cfg = super.getConfiguration(igniteInstanceName); |
| |
| TcpDiscoverySpi discoSpi = new TcpDiscoverySpi(); |
| |
| discoSpi.setIpFinder(new TcpDiscoveryVmIpFinder(true)); |
| |
| cfg.setDiscoverySpi(discoSpi); |
| |
| cfg.setCacheConfiguration(cacheConfiguration(ENTITY3_NAME), cacheConfiguration(ENTITY4_NAME), |
| cacheConfiguration("cache1"), cacheConfiguration("cache2"), cacheConfiguration("cache3"), |
| cacheConfiguration(TIMESTAMP_CACHE), cacheConfiguration(QUERY_CACHE)); |
| |
| return cfg; |
| } |
| |
| /** |
| * @param cacheName Cache name. |
| * @return Cache configuration. |
| */ |
| private CacheConfiguration cacheConfiguration(String cacheName) { |
| CacheConfiguration cfg = new CacheConfiguration(); |
| |
| cfg.setName(cacheName); |
| |
| cfg.setCacheMode(PARTITIONED); |
| |
| cfg.setAtomicityMode(ATOMIC); |
| |
| return cfg; |
| } |
| |
| /** |
| * @param igniteInstanceName Ignite instance name. |
| * @return Hibernate configuration. |
| */ |
| protected Configuration hibernateConfiguration(String igniteInstanceName) { |
| Configuration cfg = new Configuration(); |
| |
| cfg.addAnnotatedClass(Entity1.class); |
| cfg.addAnnotatedClass(Entity2.class); |
| cfg.addAnnotatedClass(Entity3.class); |
| cfg.addAnnotatedClass(Entity4.class); |
| |
| cfg.setProperty(HibernateAccessStrategyFactory.DFLT_ACCESS_TYPE_PROPERTY, AccessType.NONSTRICT_READ_WRITE.name()); |
| |
| cfg.setProperty(HBM2DDL_AUTO, "create"); |
| |
| cfg.setProperty(GENERATE_STATISTICS, "true"); |
| |
| cfg.setProperty(USE_SECOND_LEVEL_CACHE, "true"); |
| |
| cfg.setProperty(USE_QUERY_CACHE, "true"); |
| |
| cfg.setProperty(CACHE_REGION_FACTORY, HibernateRegionFactory.class.getName()); |
| |
| cfg.setProperty(RELEASE_CONNECTIONS, "on_close"); |
| |
| cfg.setProperty(HibernateAccessStrategyFactory.IGNITE_INSTANCE_NAME_PROPERTY, igniteInstanceName); |
| |
| cfg.setProperty(REGION_CACHE_PROPERTY + ENTITY1_NAME, "cache1"); |
| cfg.setProperty(REGION_CACHE_PROPERTY + ENTITY2_NAME, "cache2"); |
| cfg.setProperty(REGION_CACHE_PROPERTY + TIMESTAMP_CACHE, TIMESTAMP_CACHE); |
| cfg.setProperty(REGION_CACHE_PROPERTY + QUERY_CACHE, QUERY_CACHE); |
| |
| return cfg; |
| } |
| |
| /** |
| * Tests property {@link HibernateAccessStrategyFactory#REGION_CACHE_PROPERTY}. |
| */ |
| @Test |
| public void testPerRegionCacheProperty() { |
| testCacheUsage(1, 1, 0, 1, 1); |
| } |
| |
| /** |
| * @param expCache1 Expected size of cache with name 'cache1'. |
| * @param expCache2 Expected size of cache with name 'cache2'. |
| * @param expCache3 Expected size of cache with name 'cache3'. |
| * @param expCacheE3 Expected size of cache with name {@link #ENTITY3_NAME}. |
| * @param expCacheE4 Expected size of cache with name {@link #ENTITY4_NAME}. |
| */ |
| @SuppressWarnings("unchecked") |
| private void testCacheUsage(int expCache1, int expCache2, int expCache3, int expCacheE3, int expCacheE4) { |
| SessionFactory sesFactory = startHibernate(getTestIgniteInstanceName(0)); |
| |
| try { |
| Session ses = sesFactory.openSession(); |
| |
| try { |
| Transaction tx = ses.beginTransaction(); |
| |
| ses.save(new Entity1()); |
| ses.save(new Entity2()); |
| ses.save(new Entity3()); |
| ses.save(new Entity4()); |
| |
| tx.commit(); |
| } |
| finally { |
| ses.close(); |
| } |
| |
| ses = sesFactory.openSession(); |
| |
| try { |
| List<Entity1> list1 = ses.createCriteria(ENTITY1_NAME).list(); |
| |
| assertEquals(1, list1.size()); |
| |
| for (Entity1 e : list1) { |
| ses.load(ENTITY1_NAME, e.getId()); |
| assertNotNull(e.getId()); |
| } |
| |
| List<Entity2> list2 = ses.createCriteria(ENTITY2_NAME).list(); |
| |
| assertEquals(1, list2.size()); |
| |
| for (Entity2 e : list2) |
| assertNotNull(e.getId()); |
| |
| List<Entity3> list3 = ses.createCriteria(ENTITY3_NAME).list(); |
| |
| assertEquals(1, list3.size()); |
| |
| for (Entity3 e : list3) |
| assertNotNull(e.getId()); |
| |
| List<Entity4> list4 = ses.createCriteria(ENTITY4_NAME).list(); |
| |
| assertEquals(1, list4.size()); |
| |
| for (Entity4 e : list4) |
| assertNotNull(e.getId()); |
| } |
| finally { |
| ses.close(); |
| } |
| |
| IgniteCache<Object, Object> cache1 = grid(0).cache("cache1"); |
| IgniteCache<Object, Object> cache2 = grid(0).cache("cache2"); |
| IgniteCache<Object, Object> cache3 = grid(0).cache("cache3"); |
| IgniteCache<Object, Object> cacheE3 = grid(0).cache(ENTITY3_NAME); |
| IgniteCache<Object, Object> cacheE4 = grid(0).cache(ENTITY4_NAME); |
| |
| assertEquals("Unexpected entries: " + toSet(cache1.iterator()), expCache1, cache1.size()); |
| assertEquals("Unexpected entries: " + toSet(cache2.iterator()), expCache2, cache2.size()); |
| assertEquals("Unexpected entries: " + toSet(cache3.iterator()), expCache3, cache3.size()); |
| assertEquals("Unexpected entries: " + toSet(cacheE3.iterator()), expCacheE3, cacheE3.size()); |
| assertEquals("Unexpected entries: " + toSet(cacheE4.iterator()), expCacheE4, cacheE4.size()); |
| } |
| finally { |
| sesFactory.close(); |
| } |
| } |
| |
| /** |
| * |
| */ |
| private <K, V> Set<Cache.Entry<K, V>> toSet(Iterator<Cache.Entry<K, V>> iter) { |
| Set<Cache.Entry<K, V>> set = new HashSet<>(); |
| |
| while (iter.hasNext()) |
| set.add(iter.next()); |
| |
| return set; |
| } |
| |
| /** |
| * @param igniteInstanceName Name of the grid providing caches. |
| * @return Session factory. |
| */ |
| private SessionFactory startHibernate(String igniteInstanceName) { |
| Configuration cfg = hibernateConfiguration(igniteInstanceName); |
| |
| StandardServiceRegistryBuilder builder = new StandardServiceRegistryBuilder(); |
| |
| builder.applySetting("hibernate.connection.url", CONNECTION_URL); |
| builder.applySetting("hibernate.show_sql", false); |
| builder.applySettings(cfg.getProperties()); |
| |
| return cfg.buildSessionFactory(builder.build()); |
| } |
| |
| /** |
| * Test Hibernate entity1. |
| */ |
| @javax.persistence.Entity |
| @SuppressWarnings({"PublicInnerClass", "UnnecessaryFullyQualifiedName"}) |
| @Cacheable |
| @org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE) |
| public static class Entity1 { |
| /** */ |
| private int id; |
| |
| /** |
| * @return ID. |
| */ |
| @Id |
| @GeneratedValue |
| public int getId() { |
| return id; |
| } |
| |
| /** |
| * @param id ID. |
| */ |
| public void setId(int id) { |
| this.id = id; |
| } |
| } |
| |
| /** |
| * Test Hibernate entity2. |
| */ |
| @javax.persistence.Entity |
| @SuppressWarnings({"PublicInnerClass", "UnnecessaryFullyQualifiedName"}) |
| @Cacheable |
| @org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE) |
| public static class Entity2 { |
| /** */ |
| private int id; |
| |
| /** |
| * @return ID. |
| */ |
| @Id |
| @GeneratedValue |
| public int getId() { |
| return id; |
| } |
| |
| /** |
| * @param id ID. |
| */ |
| public void setId(int id) { |
| this.id = id; |
| } |
| } |
| |
| /** |
| * Test Hibernate entity3. |
| */ |
| @javax.persistence.Entity |
| @SuppressWarnings({"PublicInnerClass", "UnnecessaryFullyQualifiedName"}) |
| @Cacheable |
| @org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE) |
| public static class Entity3 { |
| /** */ |
| private int id; |
| |
| /** |
| * @return ID. |
| */ |
| @Id |
| @GeneratedValue |
| public int getId() { |
| return id; |
| } |
| |
| /** |
| * @param id ID. |
| */ |
| public void setId(int id) { |
| this.id = id; |
| } |
| } |
| |
| /** |
| * Test Hibernate entity4. |
| */ |
| @javax.persistence.Entity |
| @SuppressWarnings({"PublicInnerClass", "UnnecessaryFullyQualifiedName"}) |
| @Cacheable |
| @org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE) |
| public static class Entity4 { |
| /** */ |
| private int id; |
| |
| /** |
| * @return ID. |
| */ |
| @Id |
| @GeneratedValue |
| public int getId() { |
| return id; |
| } |
| |
| /** |
| * @param id ID. |
| */ |
| public void setId(int id) { |
| this.id = id; |
| } |
| } |
| } |