http://git-wip-us.apache.org/repos/asf/ignite/blob/272858db/modules/hibernate-5.3/src/test/java/org/apache/ignite/cache/hibernate/HibernateL2CacheStrategySelfTest.java
----------------------------------------------------------------------
diff --git 
a/modules/hibernate-5.3/src/test/java/org/apache/ignite/cache/hibernate/HibernateL2CacheStrategySelfTest.java
 
b/modules/hibernate-5.3/src/test/java/org/apache/ignite/cache/hibernate/HibernateL2CacheStrategySelfTest.java
new file mode 100644
index 0000000..e859284
--- /dev/null
+++ 
b/modules/hibernate-5.3/src/test/java/org/apache/ignite/cache/hibernate/HibernateL2CacheStrategySelfTest.java
@@ -0,0 +1,570 @@
+/*
+ * 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.HashMap;
+import java.util.List;
+import java.util.Map;
+import javax.cache.Cache;
+import javax.persistence.Cacheable;
+import javax.persistence.Id;
+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.hamcrest.core.Is;
+import org.hibernate.Session;
+import org.hibernate.SessionFactory;
+import org.hibernate.Transaction;
+import org.hibernate.boot.Metadata;
+import org.hibernate.boot.MetadataSources;
+import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
+import org.hibernate.cache.spi.access.AccessType;
+import org.hibernate.mapping.PersistentClass;
+import org.hibernate.mapping.RootClass;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+import static org.apache.ignite.cache.CacheAtomicityMode.TRANSACTIONAL;
+import static org.apache.ignite.cache.CacheMode.PARTITIONED;
+import static 
org.apache.ignite.cache.hibernate.HibernateAccessStrategyFactory.REGION_CACHE_PROPERTY;
+import static 
org.hibernate.cache.spi.RegionFactory.DEFAULT_QUERY_RESULTS_REGION_UNQUALIFIED_NAME;
+import static 
org.hibernate.cache.spi.RegionFactory.DEFAULT_UPDATE_TIMESTAMPS_REGION_UNQUALIFIED_NAME;
+import static org.hibernate.cfg.AvailableSettings.USE_STRUCTURED_CACHE;
+import static org.junit.Assert.assertThat;
+
+/**
+ * Tests Hibernate L2 cache configuration.
+ */
+@SuppressWarnings("unchecked")
+@RunWith(JUnit4.class)
+public class HibernateL2CacheStrategySelfTest extends GridCommonAbstractTest {
+    /** */
+    private static final String ENTITY1_NAME = Entity1.class.getName();
+
+    /** */
+    private static final String ENTITY2_NAME = Entity2.class.getName();
+
+    /** */
+    private static final String ENTITY3_NAME = Entity3.class.getName();
+
+    /** */
+    private static final String ENTITY4_NAME = Entity4.class.getName();
+
+    /** */
+    private static final String CONNECTION_URL = 
"jdbc:h2:mem:example;DB_CLOSE_DELAY=-1";
+
+    /** */
+    private SessionFactory sesFactory1;
+
+    /** {@inheritDoc} */
+    @Override protected void beforeTestsStarted() throws Exception {
+        startGrid(0);
+    }
+
+    /** {@inheritDoc} */
+    @Override protected void afterTestsStopped() throws Exception {
+        stopAllGrids();
+    }
+
+    /** {@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)cfg.getDiscoverySpi()).setIpFinder(new 
TcpDiscoveryVmIpFinder(true));
+
+        cfg.setCacheConfiguration(cacheConfiguration(ENTITY3_NAME),
+            cacheConfiguration(ENTITY4_NAME),
+            cacheConfiguration("cache1"),
+            cacheConfiguration("cache2"),
+            
cacheConfiguration(DEFAULT_UPDATE_TIMESTAMPS_REGION_UNQUALIFIED_NAME),
+            cacheConfiguration(DEFAULT_QUERY_RESULTS_REGION_UNQUALIFIED_NAME));
+
+        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(TRANSACTIONAL);
+
+        return cfg;
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    @Test
+    public void testEntityCacheReadWrite() throws Exception {
+        for (AccessType accessType : new AccessType[]{AccessType.READ_WRITE, 
AccessType.NONSTRICT_READ_WRITE})
+            testEntityCacheReadWrite(accessType);
+    }
+
+    /**
+     * @param accessType Cache access type.
+     * @throws Exception If failed.
+     */
+    private void testEntityCacheReadWrite(AccessType accessType) throws 
Exception {
+        log.info("Test access type: " + accessType);
+
+        sesFactory1 = startHibernate(accessType, getTestIgniteInstanceName(0));
+
+        try {
+            // 1 Adding.
+            Session ses = sesFactory1.openSession();
+
+            try {
+                Transaction tr = ses.beginTransaction();
+
+                ses.save(new Entity1(1, "entity-1#name-1"));
+                ses.save(new Entity2(1, "entity-2#name-1"));
+
+                tr.commit();
+            }
+            finally {
+                ses.close();
+            }
+
+            loadEntities(sesFactory1);
+
+            assertEquals(1, grid(0).cache("cache1").size());
+            assertEquals(1, grid(0).cache("cache2").size());
+            assertThat(getEntityNameFromRegion(sesFactory1, "cache1", 1), 
Is.is("entity-1#name-1"));
+            assertThat(getEntityNameFromRegion(sesFactory1, "cache2", 1), 
Is.is("entity-2#name-1"));
+
+            // 2. Updating and adding.
+            ses = sesFactory1.openSession();
+
+            try {
+                Transaction tx = ses.beginTransaction();
+
+                Entity1 e1 = (Entity1)ses.load(Entity1.class, 1);
+
+                e1.setName("entity-1#name-1#UPDATED-1");
+
+                ses.update(e1);
+
+                ses.save(new Entity2(2, "entity-2#name-2#ADDED"));
+
+                tx.commit();
+            }
+            finally {
+                ses.close();
+            }
+
+            loadEntities(sesFactory1);
+
+            assertEquals(1, grid(0).cache("cache1").size());
+            assertEquals(2, grid(0).cache("cache2").size());
+            assertThat(getEntityNameFromRegion(sesFactory1, "cache1", 1), 
Is.is("entity-1#name-1#UPDATED-1"));
+            assertThat(getEntityNameFromRegion(sesFactory1, "cache2", 1), 
Is.is("entity-2#name-1"));
+            assertThat(getEntityNameFromRegion(sesFactory1, "cache2", 2), 
Is.is("entity-2#name-2#ADDED"));
+
+            // 3. Updating, adding, updating.
+            ses = sesFactory1.openSession();
+
+            try {
+                Transaction tx = ses.beginTransaction();
+
+                Entity2 e2_1 = (Entity2)ses.load(Entity2.class, 1);
+
+                e2_1.setName("entity-2#name-1#UPDATED-1");
+
+                ses.update(e2_1);
+
+                ses.save(new Entity1(2, "entity-1#name-2#ADDED"));
+
+                Entity1 e1_1 = (Entity1)ses.load(Entity1.class, 1);
+
+                e1_1.setName("entity-1#name-1#UPDATED-2");
+
+                ses.update(e1_1);
+
+                tx.commit();
+
+            }
+            finally {
+                ses.close();
+            }
+
+            loadEntities(sesFactory1);
+
+            assertEquals(2, grid(0).cache("cache1").size());
+            assertEquals(2, grid(0).cache("cache2").size());
+            assertThat(getEntityNameFromRegion(sesFactory1, "cache2", 1), 
Is.is("entity-2#name-1#UPDATED-1"));
+            assertThat(getEntityNameFromRegion(sesFactory1, "cache1", 2), 
Is.is("entity-1#name-2#ADDED"));
+            assertThat(getEntityNameFromRegion(sesFactory1, "cache1", 1), 
Is.is("entity-1#name-1#UPDATED-2"));
+
+            ses = sesFactory1.openSession();
+
+            sesFactory1.getStatistics().logSummary();
+
+            ses.close();
+        }
+        finally {
+            cleanup();
+        }
+    }
+
+    /**
+     * @param sesFactory Session factory.
+     */
+    private void loadEntities(SessionFactory sesFactory) {
+        Session ses = sesFactory.openSession();
+
+        try {
+            List<Entity1> list1 = ses.createCriteria(ENTITY1_NAME).list();
+
+            for (Entity1 e1 : list1)
+                assertNotNull(e1.getName());
+
+            List<Entity2> list2 = ses.createCriteria(ENTITY2_NAME).list();
+
+            for (Entity2 e2 : list2)
+                assertNotNull(e2.getName());
+        }
+        finally {
+            ses.close();
+        }
+    }
+
+    /**
+     * @param sesFactory Session Factory.
+     * @param regionName Region Name.
+     * @param id Id.
+     * @return Entity Name.
+     */
+    private String getEntityNameFromRegion(SessionFactory sesFactory, String 
regionName, int id) {
+        Session ses = sesFactory.openSession();
+
+        try {
+            for (Cache.Entry<Object, Object> entry : 
grid(0).cache(regionName)) {
+                if (((HibernateKeyWrapper)entry.getKey()).id().equals(id))
+                    return (String) ((HashMap) entry.getValue()).get("name");
+            }
+
+            return null;
+        }
+        finally {
+            ses.close();
+        }
+    }
+
+    /**
+     * @param accessType Cache access typr.
+     * @param igniteInstanceName Name of the grid providing caches.
+     * @return Session factory.
+     */
+    private SessionFactory startHibernate(AccessType accessType, String 
igniteInstanceName) {
+        StandardServiceRegistryBuilder builder = new 
StandardServiceRegistryBuilder();
+
+        builder.applySetting("hibernate.connection.url", CONNECTION_URL);
+
+        for (Map.Entry<String, String> e : 
HibernateL2CacheSelfTest.hibernateProperties(igniteInstanceName, 
accessType.name()).entrySet())
+            builder.applySetting(e.getKey(), e.getValue());
+
+        builder.applySetting(USE_STRUCTURED_CACHE, "true");
+        builder.applySetting(REGION_CACHE_PROPERTY + ENTITY1_NAME, "cache1");
+        builder.applySetting(REGION_CACHE_PROPERTY + ENTITY2_NAME, "cache2");
+        builder.applySetting(REGION_CACHE_PROPERTY + 
DEFAULT_UPDATE_TIMESTAMPS_REGION_UNQUALIFIED_NAME, 
DEFAULT_UPDATE_TIMESTAMPS_REGION_UNQUALIFIED_NAME);
+        builder.applySetting(REGION_CACHE_PROPERTY + 
DEFAULT_QUERY_RESULTS_REGION_UNQUALIFIED_NAME, 
DEFAULT_QUERY_RESULTS_REGION_UNQUALIFIED_NAME);
+
+        MetadataSources metadataSources = new MetadataSources(builder.build());
+
+        metadataSources.addAnnotatedClass(Entity1.class);
+        metadataSources.addAnnotatedClass(Entity2.class);
+        metadataSources.addAnnotatedClass(Entity3.class);
+        metadataSources.addAnnotatedClass(Entity4.class);
+
+        Metadata metadata = metadataSources.buildMetadata();
+
+        for (PersistentClass entityBinding : metadata.getEntityBindings()) {
+            if (!entityBinding.isInherited())
+                
((RootClass)entityBinding).setCacheConcurrencyStrategy(accessType.getExternalName());
+        }
+
+        return metadata.buildSessionFactory();
+    }
+
+    /**
+     * Test Hibernate entity1.
+     */
+    @javax.persistence.Entity
+    @SuppressWarnings({"PublicInnerClass", "UnnecessaryFullyQualifiedName"})
+    @Cacheable
+    public static class Entity1 {
+        /** */
+        private int id;
+
+        /** */
+        private String name;
+
+        /**
+         *
+         */
+        public Entity1() {
+            // No-op.
+        }
+
+        /**
+         * @param id ID.
+         * @param name Name.
+         */
+        Entity1(int id, String name) {
+            this.id = id;
+            this.name = name;
+        }
+
+        /**
+         * @return ID.
+         */
+        @Id
+        public int getId() {
+            return id;
+        }
+
+        /**
+         * @param id ID.
+         */
+        public void setId(int id) {
+            this.id = id;
+        }
+
+        /**
+         * @return Name.
+         */
+        public String getName() {
+            return name;
+        }
+
+        /**
+         * @param name Name.
+         */
+        public void setName(String name) {
+            this.name = name;
+        }
+    }
+
+    /**
+     * Test Hibernate entity2.
+     */
+    @javax.persistence.Entity
+    @SuppressWarnings({"PublicInnerClass", "UnnecessaryFullyQualifiedName"})
+    @Cacheable
+    public static class Entity2 {
+        /** */
+        private int id;
+
+        /** */
+        private String name;
+
+        /**
+         *
+         */
+        public Entity2() {
+           // No-op.
+        }
+
+        /**
+         * @param id ID.
+         * @param name Name.
+         */
+        Entity2(int id, String name) {
+            this.id = id;
+            this.name = name;
+        }
+
+        /**
+         * @return ID.
+         */
+        @Id
+        public int getId() {
+            return id;
+        }
+
+        /**
+         * @param id ID.
+         */
+        public void setId(int id) {
+            this.id = id;
+        }
+
+        /**
+         * @return Name.
+         */
+        public String getName() {
+            return name;
+        }
+
+        /**
+         * @param name Name.
+         */
+        public void setName(String name) {
+            this.name = name;
+        }
+    }
+
+    /**
+     * Test Hibernate entity3.
+     */
+    @javax.persistence.Entity
+    @SuppressWarnings({"PublicInnerClass", "UnnecessaryFullyQualifiedName"})
+    @Cacheable
+    public static class Entity3 {
+        /** */
+        private int id;
+
+        /** */
+        private String name;
+
+        /**
+         *
+         */
+        public Entity3() {
+            // No-op.
+        }
+
+        /**
+         * @param id ID.
+         * @param name Name.
+         */
+        public Entity3(int id, String name) {
+            this.id = id;
+            this.name = name;
+        }
+
+        /**
+         * @return ID.
+         */
+        @Id
+        public int getId() {
+            return id;
+        }
+
+        /**
+         * @param id ID.
+         */
+        public void setId(int id) {
+            this.id = id;
+        }
+
+        /**
+         * @return Name.
+         */
+        public String getName() {
+            return name;
+        }
+
+        /**
+         * @param name Name.
+         */
+        public void setName(String name) {
+            this.name = name;
+        }
+    }
+
+    /**
+     * Test Hibernate entity4.
+     */
+    @javax.persistence.Entity
+    @SuppressWarnings({"PublicInnerClass", "UnnecessaryFullyQualifiedName"})
+    @Cacheable
+    public static class Entity4 {
+        /** */
+        private int id;
+
+        /** */
+        private String name;
+
+        /**
+         *
+         */
+        public Entity4() {
+            // No-op.
+        }
+
+        /**
+         * @param id ID.
+         * @param name Name.
+         */
+        public Entity4(int id, String name) {
+            this.id = id;
+            this.name = name;
+        }
+
+        /**
+         * @return ID.
+         */
+        @Id
+        public int getId() {
+            return id;
+        }
+
+        /**
+         * @param id ID.
+         */
+        public void setId(int id) {
+            this.id = id;
+        }
+
+        /**
+         * @return Name.
+         */
+        public String getName() {
+            return name;
+        }
+
+        /**
+         * @param name Name.
+         */
+        public void setName(String name) {
+            this.name = name;
+        }
+    }
+
+    /**
+     * Closes session factories and clears data from caches.
+     *
+     * @throws Exception If failed.
+     */
+    private void cleanup() throws Exception {
+        if (sesFactory1 != null)
+            sesFactory1.close();
+
+        sesFactory1 = null;
+
+        for (IgniteCacheProxy<?, ?> cache : ((IgniteKernal)grid(0)).caches())
+            cache.clear();
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/272858db/modules/hibernate-5.3/src/test/java/org/apache/ignite/cache/hibernate/HibernateL2CacheTransactionalSelfTest.java
----------------------------------------------------------------------
diff --git 
a/modules/hibernate-5.3/src/test/java/org/apache/ignite/cache/hibernate/HibernateL2CacheTransactionalSelfTest.java
 
b/modules/hibernate-5.3/src/test/java/org/apache/ignite/cache/hibernate/HibernateL2CacheTransactionalSelfTest.java
new file mode 100644
index 0000000..5175292
--- /dev/null
+++ 
b/modules/hibernate-5.3/src/test/java/org/apache/ignite/cache/hibernate/HibernateL2CacheTransactionalSelfTest.java
@@ -0,0 +1,154 @@
+/*
+ * 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.Collections;
+import javax.cache.configuration.Factory;
+import javax.transaction.Synchronization;
+import javax.transaction.TransactionManager;
+import javax.transaction.UserTransaction;
+import org.apache.commons.dbcp.managed.BasicManagedDataSource;
+import org.apache.ignite.configuration.CacheConfiguration;
+import org.apache.ignite.configuration.IgniteConfiguration;
+import org.h2.jdbcx.JdbcDataSource;
+import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
+import org.hibernate.cache.spi.access.AccessType;
+import org.hibernate.cfg.Environment;
+import 
org.hibernate.engine.jdbc.connections.internal.DatasourceConnectionProviderImpl;
+import org.hibernate.engine.jdbc.connections.spi.ConnectionProvider;
+import 
org.hibernate.engine.transaction.jta.platform.internal.AbstractJtaPlatform;
+import org.hibernate.engine.transaction.jta.platform.spi.JtaPlatform;
+import 
org.hibernate.resource.transaction.backend.jta.internal.JtaTransactionCoordinatorBuilderImpl;
+import org.jetbrains.annotations.Nullable;
+import org.objectweb.jotm.Jotm;
+
+/**
+ *
+ * Tests Hibernate L2 cache with TRANSACTIONAL access mode (Hibernate and 
Cache are configured
+ * to used the same TransactionManager).
+ */
+public class HibernateL2CacheTransactionalSelfTest extends 
HibernateL2CacheSelfTest {
+    /** */
+    private static Jotm jotm;
+
+    /**
+     */
+    private static class TestJtaPlatform extends AbstractJtaPlatform {
+        /** {@inheritDoc} */
+        @Override protected TransactionManager locateTransactionManager() {
+            return jotm.getTransactionManager();
+        }
+
+        /** {@inheritDoc} */
+        @Override protected UserTransaction locateUserTransaction() {
+            return jotm.getUserTransaction();
+        }
+    }
+
+    /**
+     */
+    @SuppressWarnings("PublicInnerClass")
+    public static class TestTmFactory implements Factory<TransactionManager> {
+        /** */
+        private static final long serialVersionUID = 0;
+
+        /** {@inheritDoc} */
+        @Override public TransactionManager create() {
+            return jotm.getTransactionManager();
+        }
+    }
+
+    /** {@inheritDoc} */
+    @Override protected void beforeTestsStarted() throws Exception {
+        jotm = new Jotm(true, false);
+
+        super.beforeTestsStarted();
+    }
+
+    /** {@inheritDoc} */
+    @Override protected void afterTestsStopped() throws Exception {
+        super.afterTestsStopped();
+
+        if (jotm != null)
+            jotm.stop();
+
+        jotm = null;
+    }
+
+    /** {@inheritDoc} */
+    @Override protected IgniteConfiguration getConfiguration(String 
igniteInstanceName) throws Exception {
+        IgniteConfiguration cfg = super.getConfiguration(igniteInstanceName);
+
+        cfg.getTransactionConfiguration().setTxManagerFactory(new 
TestTmFactory());
+        
cfg.getTransactionConfiguration().setUseJtaSynchronization(useJtaSynchronization());
+
+        return cfg;
+    }
+
+    /** {@inheritDoc} */
+    @Override protected CacheConfiguration 
transactionalRegionConfiguration(String regionName) {
+        CacheConfiguration cfg = 
super.transactionalRegionConfiguration(regionName);
+
+        cfg.setNearConfiguration(null);
+
+        return cfg;
+    }
+
+    /** {@inheritDoc} */
+    @Nullable @Override protected StandardServiceRegistryBuilder 
registryBuilder() {
+        StandardServiceRegistryBuilder builder = new 
StandardServiceRegistryBuilder();
+
+        DatasourceConnectionProviderImpl connProvider = new 
DatasourceConnectionProviderImpl();
+
+        BasicManagedDataSource dataSrc = new BasicManagedDataSource(); // 
JTA-aware data source.
+
+        dataSrc.setTransactionManager(jotm.getTransactionManager());
+
+        dataSrc.setDefaultAutoCommit(false);
+
+        JdbcDataSource h2DataSrc = new JdbcDataSource();
+
+        h2DataSrc.setURL(CONNECTION_URL);
+
+        dataSrc.setXaDataSourceInstance(h2DataSrc);
+
+        connProvider.setDataSource(dataSrc);
+
+        connProvider.configure(Collections.emptyMap());
+
+        builder.addService(ConnectionProvider.class, connProvider);
+
+        builder.addService(JtaPlatform.class, new TestJtaPlatform());
+
+        builder.applySetting(Environment.TRANSACTION_COORDINATOR_STRATEGY, 
JtaTransactionCoordinatorBuilderImpl.class.getName());
+
+        return builder;
+    }
+
+    /** {@inheritDoc} */
+    @Override protected AccessType[] accessTypes() {
+        return new AccessType[]{AccessType.TRANSACTIONAL};
+    }
+
+    /**
+     * @return Whether to use {@link Synchronization}.
+     */
+    protected boolean useJtaSynchronization() {
+        return false;
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/272858db/modules/hibernate-5.3/src/test/java/org/apache/ignite/cache/hibernate/HibernateL2CacheTransactionalUseSyncSelfTest.java
----------------------------------------------------------------------
diff --git 
a/modules/hibernate-5.3/src/test/java/org/apache/ignite/cache/hibernate/HibernateL2CacheTransactionalUseSyncSelfTest.java
 
b/modules/hibernate-5.3/src/test/java/org/apache/ignite/cache/hibernate/HibernateL2CacheTransactionalUseSyncSelfTest.java
new file mode 100644
index 0000000..44899f9
--- /dev/null
+++ 
b/modules/hibernate-5.3/src/test/java/org/apache/ignite/cache/hibernate/HibernateL2CacheTransactionalUseSyncSelfTest.java
@@ -0,0 +1,31 @@
+/*
+ * 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 javax.transaction.Synchronization;
+
+/**
+ * Tests Hibernate L2 cache with TRANSACTIONAL access mode and {@link 
Synchronization}
+ * instead of XA resource.
+ */
+public class HibernateL2CacheTransactionalUseSyncSelfTest extends 
HibernateL2CacheTransactionalSelfTest {
+    /** {@inheritDoc} */
+    @Override protected boolean useJtaSynchronization() {
+        return true;
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/272858db/modules/hibernate-5.3/src/test/java/org/apache/ignite/cache/store/hibernate/CacheHibernateBlobStoreNodeRestartTest.java
----------------------------------------------------------------------
diff --git 
a/modules/hibernate-5.3/src/test/java/org/apache/ignite/cache/store/hibernate/CacheHibernateBlobStoreNodeRestartTest.java
 
b/modules/hibernate-5.3/src/test/java/org/apache/ignite/cache/store/hibernate/CacheHibernateBlobStoreNodeRestartTest.java
new file mode 100644
index 0000000..d5496af
--- /dev/null
+++ 
b/modules/hibernate-5.3/src/test/java/org/apache/ignite/cache/store/hibernate/CacheHibernateBlobStoreNodeRestartTest.java
@@ -0,0 +1,46 @@
+/*
+ * 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.store.hibernate;
+
+import org.apache.ignite.cache.CacheAtomicityMode;
+import org.apache.ignite.cache.CacheMode;
+import org.apache.ignite.cache.store.CacheStore;
+import org.apache.ignite.configuration.NearCacheConfiguration;
+import 
org.apache.ignite.internal.processors.cache.integration.IgniteCacheStoreNodeRestartAbstractTest;
+
+public class CacheHibernateBlobStoreNodeRestartTest extends 
IgniteCacheStoreNodeRestartAbstractTest {
+    /** {@inheritDoc} */
+    @Override protected CacheStore getStore() {
+        return new CacheHibernateBlobStore();
+    }
+
+    /** {@inheritDoc} */
+    @Override protected CacheMode cacheMode() {
+        return CacheMode.PARTITIONED;
+    }
+
+    /** {@inheritDoc} */
+    @Override protected CacheAtomicityMode atomicityMode() {
+        return CacheAtomicityMode.ATOMIC;
+    }
+
+    /** {@inheritDoc} */
+    @Override protected NearCacheConfiguration nearConfiguration() {
+        return null;
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ignite/blob/272858db/modules/hibernate-5.3/src/test/java/org/apache/ignite/cache/store/hibernate/CacheHibernateBlobStoreSelfTest.java
----------------------------------------------------------------------
diff --git 
a/modules/hibernate-5.3/src/test/java/org/apache/ignite/cache/store/hibernate/CacheHibernateBlobStoreSelfTest.java
 
b/modules/hibernate-5.3/src/test/java/org/apache/ignite/cache/store/hibernate/CacheHibernateBlobStoreSelfTest.java
new file mode 100644
index 0000000..8b75bb7
--- /dev/null
+++ 
b/modules/hibernate-5.3/src/test/java/org/apache/ignite/cache/store/hibernate/CacheHibernateBlobStoreSelfTest.java
@@ -0,0 +1,118 @@
+/*
+ * 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.store.hibernate;
+
+import java.io.File;
+import java.net.URL;
+import org.apache.ignite.internal.util.typedef.internal.U;
+import 
org.apache.ignite.testframework.junits.cache.GridAbstractCacheStoreSelfTest;
+import org.hibernate.FlushMode;
+import org.hibernate.Session;
+import org.hibernate.Transaction;
+import org.hibernate.resource.transaction.spi.TransactionStatus;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+/**
+ * Cache store test.
+ */
+@RunWith(JUnit4.class)
+public class CacheHibernateBlobStoreSelfTest extends
+    GridAbstractCacheStoreSelfTest<CacheHibernateBlobStore<Object, Object>> {
+    /**
+     * @throws Exception If failed.
+     */
+    public CacheHibernateBlobStoreSelfTest() throws Exception {
+        // No-op.
+    }
+
+    /** {@inheritDoc} */
+    @Override protected void afterTest() throws Exception {
+        super.afterTest();
+
+        Session s = store.session(null);
+
+        if (s == null)
+            return;
+
+        try {
+            s.createQuery("delete from " + 
CacheHibernateBlobStoreEntry.class.getSimpleName())
+                    .setFlushMode(FlushMode.ALWAYS).executeUpdate();
+
+            Transaction hTx = s.getTransaction();
+
+            if (hTx != null && hTx.getStatus() == TransactionStatus.ACTIVE)
+                hTx.commit();
+        }
+        finally {
+            s.close();
+        }
+    }
+
+    /** {@inheritDoc} */
+    @Override protected CacheHibernateBlobStore<Object, Object> store() {
+        return new CacheHibernateBlobStore<>();
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    @Test
+    public void testConfigurationByUrl() throws Exception {
+        URL url = 
U.resolveIgniteUrl(CacheHibernateStoreFactorySelfTest.MODULE_PATH +
+            
"/src/test/resources/org/apache/ignite/cache/store/hibernate/hibernate.cfg.xml");
+
+        assert url != null;
+
+        store.setHibernateConfigurationPath(url.toString());
+
+        // Store will be implicitly initialized.
+        store.load("key");
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    @Test
+    public void testConfigurationByFile() throws Exception {
+        URL url = 
U.resolveIgniteUrl(CacheHibernateStoreFactorySelfTest.MODULE_PATH +
+                
"/src/test/resources/org/apache/ignite/cache/store/hibernate/hibernate.cfg.xml");
+
+        assert url != null;
+
+        File file = new File(url.toURI());
+
+        store.setHibernateConfigurationPath(file.getAbsolutePath());
+
+        // Store will be implicitly initialized.
+        store.load("key");
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    @Test
+    public void testConfigurationByResource() throws Exception {
+        
store.setHibernateConfigurationPath("/org/apache/ignite/cache/store/hibernate/hibernate.cfg.xml");
+
+        // Store will be implicitly initialized.
+        store.load("key");
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/272858db/modules/hibernate-5.3/src/test/java/org/apache/ignite/cache/store/hibernate/CacheHibernateStoreFactorySelfTest.java
----------------------------------------------------------------------
diff --git 
a/modules/hibernate-5.3/src/test/java/org/apache/ignite/cache/store/hibernate/CacheHibernateStoreFactorySelfTest.java
 
b/modules/hibernate-5.3/src/test/java/org/apache/ignite/cache/store/hibernate/CacheHibernateStoreFactorySelfTest.java
new file mode 100644
index 0000000..0a9a881
--- /dev/null
+++ 
b/modules/hibernate-5.3/src/test/java/org/apache/ignite/cache/store/hibernate/CacheHibernateStoreFactorySelfTest.java
@@ -0,0 +1,336 @@
+/*
+ * 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.store.hibernate;
+
+import java.sql.Connection;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.Callable;
+import javax.naming.NamingException;
+import javax.naming.Reference;
+import javax.persistence.EntityGraph;
+import javax.persistence.EntityManager;
+import javax.persistence.PersistenceUnitUtil;
+import javax.persistence.Query;
+import javax.persistence.SynchronizationType;
+import javax.persistence.criteria.CriteriaBuilder;
+import org.apache.ignite.Ignite;
+import org.apache.ignite.IgniteCache;
+import org.apache.ignite.IgniteException;
+import org.apache.ignite.Ignition;
+import org.apache.ignite.configuration.CacheConfiguration;
+import org.apache.ignite.testframework.GridTestUtils;
+import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
+import org.hibernate.Cache;
+import org.hibernate.HibernateException;
+import org.hibernate.Metamodel;
+import org.hibernate.Session;
+import org.hibernate.SessionBuilder;
+import org.hibernate.SessionFactory;
+import org.hibernate.StatelessSession;
+import org.hibernate.StatelessSessionBuilder;
+import org.hibernate.TypeHelper;
+import org.hibernate.boot.spi.SessionFactoryOptions;
+import org.hibernate.engine.spi.FilterDefinition;
+import org.hibernate.metadata.ClassMetadata;
+import org.hibernate.metadata.CollectionMetadata;
+import org.hibernate.stat.Statistics;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+/**
+ * Test for Cache jdbc blob store factory.
+ */
+@RunWith(JUnit4.class)
+public class CacheHibernateStoreFactorySelfTest extends GridCommonAbstractTest 
{
+    /** Cache name. */
+    private static final String CACHE_NAME = "test";
+
+    /** */
+    static final String MODULE_PATH = "modules/hibernate-5.3/";
+
+    /**
+     * @throws Exception If failed.
+     */
+    @Test
+    public void testCacheConfiguration() throws Exception {
+        try (Ignite ignite1 = startGrid(0)) {
+            IgniteCache<Integer, String> cache1 = 
ignite1.getOrCreateCache(cacheConfiguration());
+
+            checkStore(cache1);
+        }
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    @Test
+    public void testXmlConfiguration() throws Exception {
+        try (Ignite ignite = Ignition.start(MODULE_PATH + 
"/src/test/config/factory-cache.xml")) {
+            try(Ignite ignite1 = Ignition.start(MODULE_PATH + 
"/src/test/config/factory-cache1.xml")) {
+                checkStore(ignite.<Integer, String>cache(CACHE_NAME), 
DummySessionFactoryExt.class);
+
+                checkStore(ignite1.<Integer, String>cache(CACHE_NAME), 
DummySessionFactory.class);
+            }
+        }
+    }
+
+
+    /**
+     * @throws Exception If failed.
+     */
+    @Test
+    public void testIncorrectBeanConfiguration() {
+        GridTestUtils.assertThrows(log, new Callable<Object>() {
+            @Override
+            public Object call() throws Exception {
+                String path = MODULE_PATH + 
"/src/test/config/factory-incorrect-store-cache.xml";
+                try (Ignite ignite = Ignition.start(path)) {
+                    
ignite.cache(CACHE_NAME).getConfiguration(CacheConfiguration.class).getCacheStoreFactory().create();
+                }
+                return null;
+            }
+        }, IgniteException.class, "Failed to load bean in application 
context");
+    }
+
+    /**
+     * @return Cache configuration with store.
+     */
+    private CacheConfiguration<Integer, String> cacheConfiguration() {
+        CacheConfiguration<Integer, String> cfg = new 
CacheConfiguration<>(DEFAULT_CACHE_NAME);
+
+        CacheHibernateBlobStoreFactory<Integer, String> factory = new 
CacheHibernateBlobStoreFactory();
+
+        
factory.setHibernateConfigurationPath("/org/apache/ignite/cache/store/hibernate/hibernate.cfg.xml");
+
+        cfg.setCacheStoreFactory(factory);
+
+        return cfg;
+    }
+
+    /**
+     * @param cache Ignite cache.
+     * @param dataSrcClass Data source class.
+     * @throws Exception If store parameters is not the same as in 
configuration xml.
+     */
+    private void checkStore(IgniteCache<Integer, String> cache, Class<?> 
dataSrcClass) throws Exception {
+        CacheHibernateBlobStore store = (CacheHibernateBlobStore)cache
+            
.getConfiguration(CacheConfiguration.class).getCacheStoreFactory().create();
+
+        assertEquals(dataSrcClass,
+            GridTestUtils.getFieldValue(store, CacheHibernateBlobStore.class, 
"sesFactory").getClass());
+    }
+
+    /**
+     * @param cache Ignite cache.
+     * @throws Exception If store parameters is not the same as in 
configuration xml.
+     */
+    private void checkStore(IgniteCache<Integer, String> cache) throws 
Exception {
+        CacheHibernateBlobStore store = 
(CacheHibernateBlobStore)cache.getConfiguration(CacheConfiguration.class)
+            .getCacheStoreFactory().create();
+
+        
assertEquals("/org/apache/ignite/cache/store/hibernate/hibernate.cfg.xml",
+            GridTestUtils.getFieldValue(store, CacheHibernateBlobStore.class, 
"hibernateCfgPath"));
+    }
+
+    /**
+     *
+     */
+    public static class DummySessionFactoryExt extends DummySessionFactory {
+        /** */
+        public DummySessionFactoryExt() {
+            // No-op.
+        }
+    }
+
+    /**
+     *
+     */
+    public static class DummySessionFactory implements SessionFactory {
+        /** {@inheritDoc} */
+        @Override public SessionFactoryOptions getSessionFactoryOptions() {
+            return null;
+        }
+
+        /** {@inheritDoc} */
+        @Override public SessionBuilder withOptions() {
+            return null;
+        }
+
+        /** {@inheritDoc} */
+        @Override public Session openSession() throws HibernateException {
+            return null;
+        }
+
+        /** {@inheritDoc} */
+        @Override public Session getCurrentSession() throws HibernateException 
{
+            return null;
+        }
+
+        /** {@inheritDoc} */
+        @Override public StatelessSessionBuilder withStatelessOptions() {
+            return null;
+        }
+
+        /** {@inheritDoc} */
+        @Override public StatelessSession openStatelessSession() {
+            return null;
+        }
+
+        /** {@inheritDoc} */
+        @Override public StatelessSession openStatelessSession(Connection 
conn) {
+            return null;
+        }
+
+        /** {@inheritDoc} */
+        @Override public ClassMetadata getClassMetadata(Class entityCls) {
+            return null;
+        }
+
+        /** {@inheritDoc} */
+        @Override public ClassMetadata getClassMetadata(String entityName) {
+            return null;
+        }
+
+        /** {@inheritDoc} */
+        @Override public CollectionMetadata getCollectionMetadata(String 
roleName) {
+            return null;
+        }
+
+        /** {@inheritDoc} */
+        @Override public Map<String, ClassMetadata> getAllClassMetadata() {
+            return null;
+        }
+
+        /** {@inheritDoc} */
+        @Override public Map getAllCollectionMetadata() {
+            return null;
+        }
+
+        /** {@inheritDoc} */
+        @Override public Statistics getStatistics() {
+            return null;
+        }
+
+        /** {@inheritDoc} */
+        @Override public void close() throws HibernateException {
+        }
+
+        @Override
+        public Map<String, Object> getProperties() {
+            return null;
+        }
+
+        /** {@inheritDoc} */
+        @Override public boolean isClosed() {
+            return false;
+        }
+
+        /** {@inheritDoc} */
+        @Override public Cache getCache() {
+            return null;
+        }
+
+        @Override
+        public PersistenceUnitUtil getPersistenceUnitUtil() {
+            return null;
+        }
+
+        @Override
+        public void addNamedQuery(String name, Query query) {
+
+        }
+
+        @Override
+        public <T> T unwrap(Class<T> cls) {
+            return null;
+        }
+
+        @Override
+        public <T> void addNamedEntityGraph(String graphName, EntityGraph<T> 
entityGraph) {
+
+        }
+
+        /** {@inheritDoc} */
+        @Override public Set getDefinedFilterNames() {
+            return null;
+        }
+
+        /** {@inheritDoc} */
+        @Override public FilterDefinition getFilterDefinition(String 
filterName) throws HibernateException {
+            return null;
+        }
+
+        /** {@inheritDoc} */
+        @Override public boolean containsFetchProfileDefinition(String name) {
+            return false;
+        }
+
+        /** {@inheritDoc} */
+        @Override public TypeHelper getTypeHelper() {
+            return null;
+        }
+
+        /** {@inheritDoc} */
+        @Override public Reference getReference() throws NamingException {
+            return null;
+        }
+
+        @Override
+        public <T> List<EntityGraph<? super T>> 
findEntityGraphsByType(Class<T> aClass) {
+            return null;
+        }
+
+        @Override
+        public EntityManager createEntityManager() {
+            return null;
+        }
+
+        @Override
+        public EntityManager createEntityManager(Map map) {
+            return null;
+        }
+
+        @Override
+        public EntityManager createEntityManager(SynchronizationType 
synchronizationType) {
+            return null;
+        }
+
+        @Override
+        public EntityManager createEntityManager(SynchronizationType 
synchronizationType, Map map) {
+            return null;
+        }
+
+        @Override
+        public CriteriaBuilder getCriteriaBuilder() {
+            return null;
+        }
+
+        @Override
+        public Metamodel getMetamodel() {
+            return null;
+        }
+
+        @Override
+        public boolean isOpen() {
+            return false;
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/272858db/modules/hibernate-5.3/src/test/java/org/apache/ignite/cache/store/hibernate/CacheHibernateStoreSessionListenerSelfTest.java
----------------------------------------------------------------------
diff --git 
a/modules/hibernate-5.3/src/test/java/org/apache/ignite/cache/store/hibernate/CacheHibernateStoreSessionListenerSelfTest.java
 
b/modules/hibernate-5.3/src/test/java/org/apache/ignite/cache/store/hibernate/CacheHibernateStoreSessionListenerSelfTest.java
new file mode 100644
index 0000000..0010425
--- /dev/null
+++ 
b/modules/hibernate-5.3/src/test/java/org/apache/ignite/cache/store/hibernate/CacheHibernateStoreSessionListenerSelfTest.java
@@ -0,0 +1,242 @@
+/*
+ * 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.store.hibernate;
+
+import java.io.Serializable;
+import java.util.Map;
+import javax.cache.Cache;
+import javax.cache.configuration.Factory;
+import javax.cache.integration.CacheLoaderException;
+import javax.cache.integration.CacheWriterException;
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.Table;
+import org.apache.ignite.cache.store.CacheStore;
+import org.apache.ignite.cache.store.CacheStoreAdapter;
+import org.apache.ignite.cache.store.CacheStoreSession;
+import org.apache.ignite.cache.store.CacheStoreSessionListener;
+import org.apache.ignite.cache.store.CacheStoreSessionListenerAbstractSelfTest;
+import org.apache.ignite.cache.store.jdbc.CacheJdbcStoreSessionListener;
+import org.apache.ignite.lang.IgniteBiInClosure;
+import org.apache.ignite.resources.CacheStoreSessionResource;
+import org.hibernate.Session;
+import org.hibernate.SessionFactory;
+import org.hibernate.Transaction;
+import org.hibernate.cfg.Configuration;
+import org.hibernate.resource.transaction.spi.TransactionStatus;
+
+/**
+ * Tests for {@link CacheJdbcStoreSessionListener}.
+ */
+public class CacheHibernateStoreSessionListenerSelfTest extends 
CacheStoreSessionListenerAbstractSelfTest {
+    /** {@inheritDoc} */
+    @Override protected Factory<? extends CacheStore<Integer, Integer>> 
storeFactory() {
+        return new Factory<CacheStore<Integer, Integer>>() {
+            @Override public CacheStore<Integer, Integer> create() {
+                return new Store();
+            }
+        };
+    }
+
+    /** {@inheritDoc} */
+    @Override protected Factory<CacheStoreSessionListener> 
sessionListenerFactory() {
+        return new Factory<CacheStoreSessionListener>() {
+            @Override public CacheStoreSessionListener create() {
+                CacheHibernateStoreSessionListener lsnr = new 
CacheHibernateStoreSessionListener();
+
+                SessionFactory sesFactory = new Configuration().
+                    setProperty("hibernate.connection.url", URL).
+                    addAnnotatedClass(Table1.class).
+                    addAnnotatedClass(Table2.class).
+                    buildSessionFactory();
+
+                lsnr.setSessionFactory(sesFactory);
+
+                return lsnr;
+            }
+        };
+    }
+
+    /**
+     */
+    private static class Store extends CacheStoreAdapter<Integer, Integer> {
+        /** */
+        private static String SES_CONN_KEY = "ses_conn";
+
+        /** */
+        @CacheStoreSessionResource
+        private CacheStoreSession ses;
+
+        /** {@inheritDoc} */
+        @Override public void loadCache(IgniteBiInClosure<Integer, Integer> 
clo, Object... args) {
+            loadCacheCnt.incrementAndGet();
+
+            checkSession();
+        }
+
+        /** {@inheritDoc} */
+        @Override public Integer load(Integer key) throws CacheLoaderException 
{
+            loadCnt.incrementAndGet();
+
+            checkSession();
+
+            return null;
+        }
+
+        /** {@inheritDoc} */
+        @Override public void write(Cache.Entry<? extends Integer, ? extends 
Integer> entry)
+            throws CacheWriterException {
+            writeCnt.incrementAndGet();
+
+            checkSession();
+
+            if (write.get()) {
+                Session hibSes = ses.attachment();
+
+                switch (ses.cacheName()) {
+                    case "cache1":
+                        hibSes.save(new Table1(entry.getKey(), 
entry.getValue()));
+
+                        break;
+
+                    case "cache2":
+                        if (fail.get())
+                            throw new CacheWriterException("Expected 
failure.");
+
+                        hibSes.save(new Table2(entry.getKey(), 
entry.getValue()));
+
+                        break;
+
+                    default:
+                        throw new CacheWriterException("Wring cache: " + 
ses.cacheName());
+                }
+            }
+        }
+
+        /** {@inheritDoc} */
+        @Override public void delete(Object key) throws CacheWriterException {
+            deleteCnt.incrementAndGet();
+
+            checkSession();
+        }
+
+        /** {@inheritDoc} */
+        @Override public void sessionEnd(boolean commit) {
+            assertNull(ses.attachment());
+        }
+
+        /**
+         */
+        private void checkSession() {
+            Session hibSes = ses.attachment();
+
+            assertNotNull(hibSes);
+
+            assertTrue(hibSes.isOpen());
+
+            Transaction tx = hibSes.getTransaction();
+
+            assertNotNull(tx);
+
+            if (ses.isWithinTransaction())
+                assertEquals(TransactionStatus.ACTIVE, tx.getStatus());
+            else
+                assertFalse("Unexpected status: " + tx.getStatus(), 
tx.getStatus() == TransactionStatus.ACTIVE);
+
+            verifySameInstance(hibSes);
+        }
+
+        /**
+         * @param hibSes Session.
+         */
+        private void verifySameInstance(Session hibSes) {
+            Map<String, Session> props = ses.properties();
+
+            Session sesConn = props.get(SES_CONN_KEY);
+
+            if (sesConn == null)
+                props.put(SES_CONN_KEY, hibSes);
+            else {
+                assertSame(hibSes, sesConn);
+
+                reuseCnt.incrementAndGet();
+            }
+        }
+    }
+
+    /**
+     */
+    @Entity
+    @Table(name = "Table1")
+    private static class Table1 implements Serializable {
+        /** */
+        @Id
+        @GeneratedValue(strategy = GenerationType.IDENTITY)
+        @Column(name = "id")
+        private Integer id;
+
+        /** */
+        @Column(name = "key")
+        private int key;
+
+        /** */
+        @Column(name = "value")
+        private int value;
+
+        /**
+         * @param key Key.
+         * @param value Value.
+         */
+        private Table1(int key, int value) {
+            this.key = key;
+            this.value = value;
+        }
+    }
+
+    /**
+     */
+    @Entity
+    @Table(name = "Table2")
+    private static class Table2 implements Serializable {
+        /** */
+        @Id
+        @GeneratedValue(strategy = GenerationType.IDENTITY)
+        @Column(name = "id")
+        private Integer id;
+
+        /** */
+        @Column(name = "key")
+        private int key;
+
+        /** */
+        @Column(name = "value")
+        private int value;
+
+        /**
+         * @param key Key.
+         * @param value Value.
+         */
+        private Table2(int key, int value) {
+            this.key = key;
+            this.value = value;
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ignite/blob/272858db/modules/hibernate-5.3/src/test/java/org/apache/ignite/cache/store/hibernate/hibernate.cfg.xml
----------------------------------------------------------------------
diff --git 
a/modules/hibernate-5.3/src/test/java/org/apache/ignite/cache/store/hibernate/hibernate.cfg.xml
 
b/modules/hibernate-5.3/src/test/java/org/apache/ignite/cache/store/hibernate/hibernate.cfg.xml
new file mode 100644
index 0000000..6240599
--- /dev/null
+++ 
b/modules/hibernate-5.3/src/test/java/org/apache/ignite/cache/store/hibernate/hibernate.cfg.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+  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.
+-->
+
+
+<!DOCTYPE hibernate-configuration PUBLIC
+        "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
+        "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd";>
+
+<hibernate-configuration>
+    <session-factory>
+        <!-- Show SQL. -->
+        <property name="show_sql">true</property>
+
+        <!-- Database connection settings (private in-memory database). -->
+        <property 
name="connection.url">jdbc:h2:mem:example;DB_CLOSE_DELAY=-1</property>
+
+        <!-- Only validate the database schema on startup in production mode. 
-->
+        <property name="hbm2ddl.auto">update</property>
+
+        <!-- H2 dialect. -->
+        <property 
name="hibernate.dialect">org.hibernate.dialect.H2Dialect</property>
+
+        <!-- Mappings. -->
+        <mapping 
resource="org/apache/ignite/cache/store/hibernate/CacheHibernateBlobStoreEntry.hbm.xml"/>
+    </session-factory>
+</hibernate-configuration>

http://git-wip-us.apache.org/repos/asf/ignite/blob/272858db/modules/hibernate-5.3/src/test/java/org/apache/ignite/cache/store/hibernate/package-info.java
----------------------------------------------------------------------
diff --git 
a/modules/hibernate-5.3/src/test/java/org/apache/ignite/cache/store/hibernate/package-info.java
 
b/modules/hibernate-5.3/src/test/java/org/apache/ignite/cache/store/hibernate/package-info.java
new file mode 100644
index 0000000..8af9886
--- /dev/null
+++ 
b/modules/hibernate-5.3/src/test/java/org/apache/ignite/cache/store/hibernate/package-info.java
@@ -0,0 +1,22 @@
+/*
+ * 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 description. -->
+ * Contains internal tests or test related classes and interfaces.
+ */
+package org.apache.ignite.cache.store.hibernate;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ignite/blob/272858db/modules/hibernate-5.3/src/test/java/org/apache/ignite/testsuites/IgniteBinaryHibernate53TestSuite.java
----------------------------------------------------------------------
diff --git 
a/modules/hibernate-5.3/src/test/java/org/apache/ignite/testsuites/IgniteBinaryHibernate53TestSuite.java
 
b/modules/hibernate-5.3/src/test/java/org/apache/ignite/testsuites/IgniteBinaryHibernate53TestSuite.java
new file mode 100644
index 0000000..51842a8
--- /dev/null
+++ 
b/modules/hibernate-5.3/src/test/java/org/apache/ignite/testsuites/IgniteBinaryHibernate53TestSuite.java
@@ -0,0 +1,37 @@
+/*
+ * 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.testsuites;
+
+import junit.framework.TestSuite;
+import org.apache.ignite.internal.binary.BinaryMarshaller;
+import org.apache.ignite.testframework.config.GridTestProperties;
+
+/**
+ *
+ */
+public class IgniteBinaryHibernate53TestSuite extends TestSuite {
+    /**
+     * @return Test suite.
+     * @throws Exception If failed.
+     */
+    public static TestSuite suite() throws Exception {
+        GridTestProperties.setProperty(GridTestProperties.MARSH_CLASS_NAME, 
BinaryMarshaller.class.getName());
+
+        return IgniteHibernate53TestSuite.suite();
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/272858db/modules/hibernate-5.3/src/test/java/org/apache/ignite/testsuites/IgniteHibernate53TestSuite.java
----------------------------------------------------------------------
diff --git 
a/modules/hibernate-5.3/src/test/java/org/apache/ignite/testsuites/IgniteHibernate53TestSuite.java
 
b/modules/hibernate-5.3/src/test/java/org/apache/ignite/testsuites/IgniteHibernate53TestSuite.java
new file mode 100644
index 0000000..794cffe
--- /dev/null
+++ 
b/modules/hibernate-5.3/src/test/java/org/apache/ignite/testsuites/IgniteHibernate53TestSuite.java
@@ -0,0 +1,61 @@
+/*
+ * 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.testsuites;
+
+import junit.framework.JUnit4TestAdapter;
+import junit.framework.TestSuite;
+import org.apache.ignite.cache.hibernate.HibernateL2CacheConfigurationSelfTest;
+import org.apache.ignite.cache.hibernate.HibernateL2CacheMultiJvmTest;
+import org.apache.ignite.cache.hibernate.HibernateL2CacheSelfTest;
+import org.apache.ignite.cache.hibernate.HibernateL2CacheStrategySelfTest;
+import org.apache.ignite.cache.hibernate.HibernateL2CacheTransactionalSelfTest;
+import 
org.apache.ignite.cache.hibernate.HibernateL2CacheTransactionalUseSyncSelfTest;
+import 
org.apache.ignite.cache.store.hibernate.CacheHibernateBlobStoreNodeRestartTest;
+import org.apache.ignite.cache.store.hibernate.CacheHibernateBlobStoreSelfTest;
+import 
org.apache.ignite.cache.store.hibernate.CacheHibernateStoreFactorySelfTest;
+import 
org.apache.ignite.cache.store.hibernate.CacheHibernateStoreSessionListenerSelfTest;
+
+/**
+ * Hibernate integration tests.
+ */
+public class IgniteHibernate53TestSuite extends TestSuite {
+    /**
+     * @return Test suite.
+     */
+    public static TestSuite suite() {
+        TestSuite suite = new TestSuite("Hibernate5 Integration Test Suite");
+
+        // Hibernate L2 cache.
+        suite.addTest(new JUnit4TestAdapter(HibernateL2CacheSelfTest.class));
+        suite.addTest(new 
JUnit4TestAdapter(HibernateL2CacheTransactionalSelfTest.class));
+        suite.addTest(new 
JUnit4TestAdapter(HibernateL2CacheTransactionalUseSyncSelfTest.class));
+        suite.addTest(new 
JUnit4TestAdapter(HibernateL2CacheConfigurationSelfTest.class));
+        suite.addTest(new 
JUnit4TestAdapter(HibernateL2CacheStrategySelfTest.class));
+        suite.addTest(new 
JUnit4TestAdapter(HibernateL2CacheMultiJvmTest.class));
+
+        suite.addTest(new 
JUnit4TestAdapter(CacheHibernateBlobStoreSelfTest.class));
+
+        suite.addTest(new 
JUnit4TestAdapter(CacheHibernateBlobStoreNodeRestartTest.class));
+
+        suite.addTest(new 
JUnit4TestAdapter(CacheHibernateStoreSessionListenerSelfTest.class));
+
+        suite.addTest(new 
JUnit4TestAdapter(CacheHibernateStoreFactorySelfTest.class));
+
+        return suite;
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/272858db/modules/hibernate-5.3/src/test/resources/org/apache/ignite/cache/store/hibernate/hibernate.cfg.xml
----------------------------------------------------------------------
diff --git 
a/modules/hibernate-5.3/src/test/resources/org/apache/ignite/cache/store/hibernate/hibernate.cfg.xml
 
b/modules/hibernate-5.3/src/test/resources/org/apache/ignite/cache/store/hibernate/hibernate.cfg.xml
new file mode 100644
index 0000000..6240599
--- /dev/null
+++ 
b/modules/hibernate-5.3/src/test/resources/org/apache/ignite/cache/store/hibernate/hibernate.cfg.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+  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.
+-->
+
+
+<!DOCTYPE hibernate-configuration PUBLIC
+        "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
+        "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd";>
+
+<hibernate-configuration>
+    <session-factory>
+        <!-- Show SQL. -->
+        <property name="show_sql">true</property>
+
+        <!-- Database connection settings (private in-memory database). -->
+        <property 
name="connection.url">jdbc:h2:mem:example;DB_CLOSE_DELAY=-1</property>
+
+        <!-- Only validate the database schema on startup in production mode. 
-->
+        <property name="hbm2ddl.auto">update</property>
+
+        <!-- H2 dialect. -->
+        <property 
name="hibernate.dialect">org.hibernate.dialect.H2Dialect</property>
+
+        <!-- Mappings. -->
+        <mapping 
resource="org/apache/ignite/cache/store/hibernate/CacheHibernateBlobStoreEntry.hbm.xml"/>
+    </session-factory>
+</hibernate-configuration>

http://git-wip-us.apache.org/repos/asf/ignite/blob/272858db/modules/hibernate-core/src/main/java/org/apache/ignite/cache/hibernate/HibernateAccessStrategyAdapter.java
----------------------------------------------------------------------
diff --git 
a/modules/hibernate-core/src/main/java/org/apache/ignite/cache/hibernate/HibernateAccessStrategyAdapter.java
 
b/modules/hibernate-core/src/main/java/org/apache/ignite/cache/hibernate/HibernateAccessStrategyAdapter.java
index 557b018..44edf8e 100644
--- 
a/modules/hibernate-core/src/main/java/org/apache/ignite/cache/hibernate/HibernateAccessStrategyAdapter.java
+++ 
b/modules/hibernate-core/src/main/java/org/apache/ignite/cache/hibernate/HibernateAccessStrategyAdapter.java
@@ -100,7 +100,8 @@ public abstract class HibernateAccessStrategyAdapter {
      * @param cache Cache.
      * @param eConverter Exception converter.
      */
-    protected HibernateAccessStrategyAdapter(Ignite ignite,
+    protected HibernateAccessStrategyAdapter(
+        Ignite ignite,
         HibernateCacheProxy cache,
         HibernateExceptionConverter eConverter) {
         this.cache = cache;
@@ -124,7 +125,12 @@ public abstract class HibernateAccessStrategyAdapter {
      */
     @Nullable public Object get(Object key) {
         try {
-            return cache.get(key);
+            Object val = cache.get(key);
+
+            if (log.isDebugEnabled())
+                log.debug("Get [cache=" + cache.name() + ", key=" + key + ", 
val=" + val + ']');
+
+            return val;
         }
         catch (IgniteCheckedException e) {
             throw convertException(e);
@@ -147,6 +153,9 @@ public abstract class HibernateAccessStrategyAdapter {
      * @param val Value.
      */
     public void putFromLoad(Object key, Object val) {
+        if (log.isDebugEnabled())
+            log.debug("Put from load [cache=" + cache.name() + ", key=" + key 
+ ", val=" + val + ']');
+
         try {
             cache.put(key, val);
         }
@@ -225,6 +234,9 @@ public abstract class HibernateAccessStrategyAdapter {
      * Called to remove all data from cache without regard to transaction.
      */
     public void evictAll() {
+        if (log.isDebugEnabled())
+            log.debug("Evict all [cache=" + cache.name() + ']');
+
         try {
             evictAll(cache);
         }
@@ -337,4 +349,4 @@ public abstract class HibernateAccessStrategyAdapter {
             cacheName = U.readString(in);
         }
     }
-}
\ No newline at end of file
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/272858db/modules/hibernate-core/src/main/java/org/apache/ignite/cache/hibernate/HibernateAccessStrategyFactory.java
----------------------------------------------------------------------
diff --git 
a/modules/hibernate-core/src/main/java/org/apache/ignite/cache/hibernate/HibernateAccessStrategyFactory.java
 
b/modules/hibernate-core/src/main/java/org/apache/ignite/cache/hibernate/HibernateAccessStrategyFactory.java
index 0226c1c..c48d482 100644
--- 
a/modules/hibernate-core/src/main/java/org/apache/ignite/cache/hibernate/HibernateAccessStrategyFactory.java
+++ 
b/modules/hibernate-core/src/main/java/org/apache/ignite/cache/hibernate/HibernateAccessStrategyFactory.java
@@ -19,8 +19,9 @@ package org.apache.ignite.cache.hibernate;
 
 import java.util.HashMap;
 import java.util.Map;
-import java.util.Properties;
 import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.atomic.AtomicReference;
+import java.util.function.Supplier;
 import org.apache.ignite.Ignite;
 import org.apache.ignite.IgniteException;
 import org.apache.ignite.IgniteLogger;
@@ -54,9 +55,6 @@ public class HibernateAccessStrategyFactory {
     /** Hibernate L2 cache Ignite instance name property name. */
     public static final String IGNITE_INSTANCE_NAME_PROPERTY = 
"org.apache.ignite.hibernate.ignite_instance_name";
 
-    /** Default cache property name. */
-    public static final String DFLT_CACHE_NAME_PROPERTY = 
"org.apache.ignite.hibernate.default_cache";
-
     /** Property prefix used to specify region name to cache name mapping. */
     public static final String REGION_CACHE_PROPERTY = 
"org.apache.ignite.hibernate.region_cache.";
 
@@ -66,13 +64,16 @@ public class HibernateAccessStrategyFactory {
     /** */
     public static final String GRID_CONFIG_PROPERTY = 
"org.apache.ignite.hibernate.grid_config";
 
+    /** Disable atomicity check when caches are created lazily. */
+    public static final String VERIFY_ATOMICITY = 
"org.apache.ignite.hibernate.verify_atomicity";
+
+    /** When set, all cache names in ignite will be fetched using the 
specified prefix. */
+    public static final String CACHE_PREFIX = 
"org.apache.ignite.hibernate.cache_prefix";
+
     /** Grid providing caches. */
     private Ignite ignite;
 
-    /** Default cache. */
-    private HibernateCacheProxy dfltCache;
-
-    /** Region name to cache name mapping. */
+    /** Region name to cache name (without prefix) mapping. */
     private final Map<String, String> regionCaches = new HashMap<>();
 
     /** */
@@ -81,6 +82,12 @@ public class HibernateAccessStrategyFactory {
     /** */
     private final ConcurrentHashMap<String, ThreadLocal> threadLocMap = new 
ConcurrentHashMap<>();
 
+    /** */
+    private String cachePrefix;
+
+    /** */
+    private boolean verifyAtomicity = true;
+
     /**
      * @param keyTransformer Key transformer.
      * @param eConverter Exception converter.
@@ -91,53 +98,45 @@ public class HibernateAccessStrategyFactory {
     }
 
     /**
-     * @param props Properties.
+     * @param cfgValues {@link Map} of config values.
      */
-    public void start(Properties props)  {
-        String gridCfg = props.getProperty(GRID_CONFIG_PROPERTY);
-        String igniteInstanceName = 
props.getProperty(IGNITE_INSTANCE_NAME_PROPERTY);
+    public void start(Map<Object, Object> cfgValues)  {
+        cachePrefix = cfgValues.getOrDefault(CACHE_PREFIX, "").toString();
+
+        verifyAtomicity = 
Boolean.valueOf(cfgValues.getOrDefault(VERIFY_ATOMICITY, 
verifyAtomicity).toString());
 
-        if (igniteInstanceName == null)
-            igniteInstanceName = props.getProperty(GRID_NAME_PROPERTY);
+        Object gridCfg = cfgValues.get(GRID_CONFIG_PROPERTY);
+
+        Object igniteInstanceName = 
cfgValues.get(IGNITE_INSTANCE_NAME_PROPERTY);
 
         if (gridCfg != null) {
             try {
-                ignite = G.start(gridCfg);
+                ignite = G.start(gridCfg.toString());
             }
             catch (IgniteException e) {
                 throw eConverter.convert(e);
             }
         }
         else
-            ignite = Ignition.ignite(igniteInstanceName);
+            ignite = Ignition.ignite(igniteInstanceName == null ? null : 
igniteInstanceName.toString());
 
-        for (Map.Entry<Object, Object> prop : props.entrySet()) {
-            String key = prop.getKey().toString();
+        for (Map.Entry entry : cfgValues.entrySet()) {
+            String key = entry.getKey().toString();
 
             if (key.startsWith(REGION_CACHE_PROPERTY)) {
                 String regionName = 
key.substring(REGION_CACHE_PROPERTY.length());
 
-                String cacheName = prop.getValue().toString();
+                String cacheName = entry.getValue().toString();
 
-                if (((IgniteKernal)ignite).getCache(cacheName) == null)
+                if (((IgniteKernal) ignite).getCache(cachePrefix + cacheName) 
== null) {
                     throw new IllegalArgumentException("Cache '" + cacheName + 
"' specified for region '" + regionName + "' " +
                         "is not configured.");
+                }
 
                 regionCaches.put(regionName, cacheName);
             }
         }
 
-        String dfltCacheName = props.getProperty(DFLT_CACHE_NAME_PROPERTY);
-
-        if (dfltCacheName != null) {
-            IgniteInternalCache<Object, Object> dfltCache = 
((IgniteKernal)ignite).getCache(dfltCacheName);
-
-            if (dfltCache == null)
-                throw new IllegalArgumentException("Cache specified as default 
is not configured: " + dfltCacheName);
-
-            this.dfltCache = new HibernateCacheProxy(dfltCache, 
keyTransformer);
-        }
-
         IgniteLogger log = ignite.log().getLogger(getClass());
 
         if (log.isDebugEnabled())
@@ -158,19 +157,48 @@ public class HibernateAccessStrategyFactory {
     HibernateCacheProxy regionCache(String regionName) {
         String cacheName = regionCaches.get(regionName);
 
-        if (cacheName == null) {
-            if (dfltCache != null)
-                return dfltCache;
-
+        if (cacheName == null)
             cacheName = regionName;
+
+        cacheName = cachePrefix + cacheName;
+
+        Supplier<IgniteInternalCache<Object, Object>> lazyCache = new 
LazyCacheSupplier(cacheName, regionName);
+
+        return new HibernateCacheProxy(cacheName, lazyCache, keyTransformer);
+    }
+
+    /** */
+    private class LazyCacheSupplier implements 
Supplier<IgniteInternalCache<Object, Object>> {
+        /** */
+        private final AtomicReference<IgniteInternalCache<Object, Object>> 
reference = new AtomicReference<>();
+
+        /** */
+        private final String cacheName;
+
+        /** */
+        private final String regionName;
+
+        /** */
+        private LazyCacheSupplier(String cacheName, String regionName) {
+            this.cacheName = cacheName;
+            this.regionName = regionName;
         }
 
-        IgniteInternalCache<Object, Object> cache = 
((IgniteKernal)ignite).getCache(cacheName);
+        /** {@inheritDoc} */
+        @Override public IgniteInternalCache<Object, Object> get() {
+            IgniteInternalCache<Object, Object> cache = reference.get();
 
-        if (cache == null)
-            throw new IllegalArgumentException("Cache '" + cacheName + "' for 
region '" + regionName + "' is not configured.");
+            if (cache == null) {
+                cache = ((IgniteKernal)ignite).getCache(cacheName);
 
-        return new HibernateCacheProxy(cache, keyTransformer);
+                if (cache == null)
+                    throw new IllegalArgumentException("Cache '" + cacheName + 
"' for region '" + regionName + "' is not configured.");
+
+                reference.compareAndSet(null, cache);
+            }
+
+            return cache;
+        }
     }
 
     /**
@@ -203,9 +231,12 @@ public class HibernateAccessStrategyFactory {
      * @return Access strategy implementation.
      */
     HibernateAccessStrategyAdapter createReadWriteStrategy(HibernateCacheProxy 
cache) {
-        if (cache.configuration().getAtomicityMode() != TRANSACTIONAL)
-            throw new IllegalArgumentException("Hibernate READ-WRITE access 
strategy must have Ignite cache with " +
-                "'TRANSACTIONAL' atomicity mode: " + cache.name());
+        if (verifyAtomicity) {
+            if (cache.configuration().getAtomicityMode() != TRANSACTIONAL) {
+                throw new IllegalArgumentException("Hibernate READ-WRITE 
access strategy must have Ignite cache with " +
+                    "'TRANSACTIONAL' atomicity mode: " + cache.name());
+            }
+        }
 
         return new HibernateReadWriteAccessStrategy(ignite, cache, threadLoc, 
eConverter);
     }
@@ -215,19 +246,22 @@ public class HibernateAccessStrategyFactory {
      * @return Access strategy implementation.
      */
     HibernateAccessStrategyAdapter 
createTransactionalStrategy(HibernateCacheProxy cache) {
-        if (cache.configuration().getAtomicityMode() != TRANSACTIONAL)
-            throw new IllegalArgumentException("Hibernate TRANSACTIONAL access 
strategy must have Ignite cache with " +
-                "'TRANSACTIONAL' atomicity mode: " + cache.name());
-
-        TransactionConfiguration txCfg = 
ignite.configuration().getTransactionConfiguration();
-
-        if (txCfg == null ||
-            (txCfg.getTxManagerFactory() == null
-                && txCfg.getTxManagerLookupClassName() == null
-                && 
cache.configuration().getTransactionManagerLookupClassName() == null)) {
-            throw new IllegalArgumentException("Hibernate TRANSACTIONAL access 
strategy must have Ignite with " +
-                "Factory<TransactionManager> configured (see 
IgniteConfiguration." +
-                "getTransactionConfiguration().setTxManagerFactory()): " + 
cache.name());
+        if (verifyAtomicity) {
+            if (cache.configuration().getAtomicityMode() != TRANSACTIONAL) {
+                throw new IllegalArgumentException("Hibernate TRANSACTIONAL 
access strategy must have Ignite cache with " +
+                    "'TRANSACTIONAL' atomicity mode: " + cache.name());
+            }
+
+            TransactionConfiguration txCfg = 
ignite.configuration().getTransactionConfiguration();
+
+            if (txCfg == null ||
+                (txCfg.getTxManagerFactory() == null
+                    && txCfg.getTxManagerLookupClassName() == null
+                    && 
cache.configuration().getTransactionManagerLookupClassName() == null)) {
+                throw new IllegalArgumentException("Hibernate TRANSACTIONAL 
access strategy must have Ignite with " +
+                    "Factory<TransactionManager> configured (see 
IgniteConfiguration." +
+                    "getTransactionConfiguration().setTxManagerFactory()): " + 
cache.name());
+            }
         }
 
         return new HibernateTransactionalAccessStrategy(ignite, cache, 
eConverter);

Reply via email to