ignite-1794 Added support for Hibernate5

Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/7102d532
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/7102d532
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/7102d532

Branch: refs/heads/ignite-3477-master
Commit: 7102d532c3efa144de7510f21beb6feceab53dae
Parents: 73b6b66
Author: sboikov <[email protected]>
Authored: Mon Apr 10 15:21:09 2017 +0300
Committer: sboikov <[email protected]>
Committed: Mon Apr 10 15:21:09 2017 +0300

----------------------------------------------------------------------
 assembly/dependencies-fabric.xml                |    1 +
 assembly/libs/README.txt                        |    1 +
 .../GridCacheConditionalDeploymentSelfTest.java |   19 +-
 .../cache/hibernate/HibernateCacheProxy.java    |    2 +-
 .../cache/hibernate/HibernateKeyWrapper.java    |   34 +-
 .../cache/hibernate/HibernateRegionFactory.java |    3 +-
 .../hibernate/HibernateL2CacheSelfTest.java     |    2 +-
 modules/hibernate5/README.txt                   |   48 +
 modules/hibernate5/licenses/apache-2.0.txt      |  202 ++
 modules/hibernate5/pom.xml                      |  146 ++
 .../HibernateAbstractRegionAccessStrategy.java  |   99 +
 .../HibernateAccessStrategyAdapter.java         |  379 ++++
 .../cache/hibernate/HibernateCacheProxy.java    |  811 ++++++++
 .../hibernate/HibernateCollectionRegion.java    |  114 +
 .../cache/hibernate/HibernateEntityRegion.java  |  129 ++
 .../hibernate/HibernateGeneralDataRegion.java   |   72 +
 .../hibernate/HibernateKeyTransformer.java      |   28 +
 .../cache/hibernate/HibernateKeyWrapper.java    |  108 +
 .../hibernate/HibernateNaturalIdRegion.java     |  113 +
 .../HibernateNonStrictAccessStrategy.java       |  222 ++
 .../hibernate/HibernateQueryResultsRegion.java  |   70 +
 .../HibernateReadOnlyAccessStrategy.java        |  107 +
 .../HibernateReadWriteAccessStrategy.java       |  328 +++
 .../ignite/cache/hibernate/HibernateRegion.java |   99 +
 .../cache/hibernate/HibernateRegionFactory.java |  255 +++
 .../hibernate/HibernateTimestampsRegion.java    |   39 +
 .../HibernateTransactionalAccessStrategy.java   |  141 ++
 .../HibernateTransactionalDataRegion.java       |  107 +
 .../ignite/cache/hibernate/package-info.java    |   24 +
 .../hibernate/CacheHibernateBlobStore.java      |  542 +++++
 .../CacheHibernateBlobStoreEntry.hbm.xml        |   31 +
 .../hibernate/CacheHibernateBlobStoreEntry.java |   89 +
 .../CacheHibernateBlobStoreFactory.java         |  235 +++
 .../CacheHibernateStoreSessionListener.java     |  223 ++
 .../cache/store/hibernate/package-info.java     |   22 +
 .../src/test/config/factory-cache.xml           |   59 +
 .../src/test/config/factory-cache1.xml          |   61 +
 .../config/factory-incorrect-store-cache.xml    |   56 +
 .../HibernateL2CacheConfigurationSelfTest.java  |  409 ++++
 .../hibernate/HibernateL2CacheSelfTest.java     | 1948 ++++++++++++++++++
 .../HibernateL2CacheTransactionalSelfTest.java  |  154 ++
 ...nateL2CacheTransactionalUseSyncSelfTest.java |   31 +
 .../CacheHibernateBlobStoreNodeRestartTest.java |   54 +
 .../CacheHibernateBlobStoreSelfTest.java        |  113 +
 .../CacheHibernateStoreFactorySelfTest.java     |  326 +++
 ...heHibernateStoreSessionListenerSelfTest.java |  241 +++
 .../cache/store/hibernate/hibernate.cfg.xml     |   42 +
 .../cache/store/hibernate/package-info.java     |   22 +
 .../IgniteBinaryHibernate5TestSuite.java        |   37 +
 .../testsuites/IgniteHibernate5TestSuite.java   |   57 +
 pom.xml                                         |    1 +
 51 files changed, 8435 insertions(+), 21 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/7102d532/assembly/dependencies-fabric.xml
----------------------------------------------------------------------
diff --git a/assembly/dependencies-fabric.xml b/assembly/dependencies-fabric.xml
index d4000d6..202ca16 100644
--- a/assembly/dependencies-fabric.xml
+++ b/assembly/dependencies-fabric.xml
@@ -131,6 +131,7 @@
                 <exclude>org.apache.ignite:ignite-codegen</exclude>
                 <exclude>org.apache.ignite:ignite-apache-license-gen</exclude>
                 <exclude>org.apache.ignite:ignite-hibernate</exclude>
+                <exclude>org.apache.ignite:ignite-hibernate5</exclude>
                 <exclude>org.apache.ignite:ignite-schedule</exclude>
                 <exclude>org.apache.ignite:ignite-geospatial</exclude>
                 <exclude>org.apache.ignite:ignite-appserver-test</exclude>

http://git-wip-us.apache.org/repos/asf/ignite/blob/7102d532/assembly/libs/README.txt
----------------------------------------------------------------------
diff --git a/assembly/libs/README.txt b/assembly/libs/README.txt
index 9902e8c..a5e8a01 100644
--- a/assembly/libs/README.txt
+++ b/assembly/libs/README.txt
@@ -81,6 +81,7 @@ The following modules are available:
 - ignite-gce (for automatic cluster discovery on Google Compute Engine)
 - ignite-hadoop (for Apache Hadoop Accelerator)
 - ignite-hibernate (for Hibernate integration)
+- ignite-hibernate5 (for Hibernate5 integration)
 - ignite-indexing (for SQL querying and indexing)
 - ignite-jcl (for Apache Commons logging)
 - ignite-jms11 (for streaming messaging from JMS queue or topic into Ignite)

http://git-wip-us.apache.org/repos/asf/ignite/blob/7102d532/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheConditionalDeploymentSelfTest.java
----------------------------------------------------------------------
diff --git 
a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheConditionalDeploymentSelfTest.java
 
b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheConditionalDeploymentSelfTest.java
index 8fdd752..b26b582 100644
--- 
a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheConditionalDeploymentSelfTest.java
+++ 
b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheConditionalDeploymentSelfTest.java
@@ -29,6 +29,7 @@ import 
org.apache.ignite.plugin.extensions.communication.Message;
 import org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi;
 import org.apache.ignite.spi.discovery.tcp.ipfinder.TcpDiscoveryIpFinder;
 import org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder;
+import org.apache.ignite.testframework.config.GridTestProperties;
 import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
 
 import static org.apache.ignite.cache.CacheAtomicityMode.TRANSACTIONAL;
@@ -122,17 +123,23 @@ public class GridCacheConditionalDeploymentSelfTest 
extends GridCommonAbstractTe
      * @throws Exception In case of error.
      */
     public void testAddedDeploymentInfo() throws Exception {
-        GridCacheIoManager ioMgr = cacheIoManager();
+        GridCacheContext ctx = cacheContext();
 
-        TestMessage msg = new TestMessage();
+        if (grid(0).configuration().getMarshaller() instanceof 
BinaryMarshaller)
+            assertFalse(ctx.deploymentEnabled());
+        else {
+            GridCacheIoManager ioMgr = cacheIoManager();
 
-        assertNull(msg.deployInfo());
+            TestMessage msg = new TestMessage();
 
-        msg.addDepInfo = true;
+            assertNull(msg.deployInfo());
 
-        IgniteUtils.invoke(GridCacheIoManager.class, ioMgr, "onSend", msg, 
grid(1).cluster().localNode().id());
+            msg.addDepInfo = true;
 
-        assertNotNull(msg.deployInfo());
+            IgniteUtils.invoke(GridCacheIoManager.class, ioMgr, "onSend", msg, 
grid(1).cluster().localNode().id());
+
+            assertNotNull(msg.deployInfo());
+        }
     }
 
     /**

http://git-wip-us.apache.org/repos/asf/ignite/blob/7102d532/modules/hibernate/src/main/java/org/apache/ignite/cache/hibernate/HibernateCacheProxy.java
----------------------------------------------------------------------
diff --git 
a/modules/hibernate/src/main/java/org/apache/ignite/cache/hibernate/HibernateCacheProxy.java
 
b/modules/hibernate/src/main/java/org/apache/ignite/cache/hibernate/HibernateCacheProxy.java
index 824cac4..69d9097 100644
--- 
a/modules/hibernate/src/main/java/org/apache/ignite/cache/hibernate/HibernateCacheProxy.java
+++ 
b/modules/hibernate/src/main/java/org/apache/ignite/cache/hibernate/HibernateCacheProxy.java
@@ -50,7 +50,7 @@ import org.apache.ignite.transactions.TransactionIsolation;
 import org.jetbrains.annotations.Nullable;
 
 /**
- *
+ * Hibernate cache proxy.
  */
 public class HibernateCacheProxy implements IgniteInternalCache<Object, 
Object> {
     /** Delegate. */

http://git-wip-us.apache.org/repos/asf/ignite/blob/7102d532/modules/hibernate/src/main/java/org/apache/ignite/cache/hibernate/HibernateKeyWrapper.java
----------------------------------------------------------------------
diff --git 
a/modules/hibernate/src/main/java/org/apache/ignite/cache/hibernate/HibernateKeyWrapper.java
 
b/modules/hibernate/src/main/java/org/apache/ignite/cache/hibernate/HibernateKeyWrapper.java
index acf8b3d..7de440e 100644
--- 
a/modules/hibernate/src/main/java/org/apache/ignite/cache/hibernate/HibernateKeyWrapper.java
+++ 
b/modules/hibernate/src/main/java/org/apache/ignite/cache/hibernate/HibernateKeyWrapper.java
@@ -17,6 +17,8 @@
 
 package org.apache.ignite.cache.hibernate;
 
+import org.apache.ignite.internal.util.typedef.internal.S;
+
 /**
  * Hibernate cache key wrapper.
  */
@@ -27,36 +29,44 @@ public class HibernateKeyWrapper {
     /** Entry. */
     private final String entry;
 
+    /** */
+    private final String tenantId;
+
     /**
      * @param key Key.
      * @param entry Entry.
+     * @param tenantId Tenant ID.
      */
-    public HibernateKeyWrapper(Object key, String entry) {
+    HibernateKeyWrapper(Object key, String entry, String tenantId) {
         this.key = key;
         this.entry = entry;
+        this.tenantId = tenantId;
     }
 
     /** {@inheritDoc} */
     @Override public boolean equals(Object o) {
-        if (this == o)
-            return true;
+        if (this == o) return true;
+
         if (o == null || getClass() != o.getClass())
             return false;
 
-        HibernateKeyWrapper wrapper = (HibernateKeyWrapper)o;
-
-        if (key != null ? !key.equals(wrapper.key) : wrapper.key != null)
-            return false;
+        HibernateKeyWrapper that = (HibernateKeyWrapper) o;
 
-        return entry != null ? entry.equals(wrapper.entry) : wrapper.entry == 
null;
+        return (key != null ? key.equals(that.key) : that.key == null) &&
+            (entry != null ? entry.equals(that.entry) : that.entry == null) &&
+            (tenantId != null ? tenantId.equals(that.tenantId) : that.tenantId 
== null);
     }
 
     /** {@inheritDoc} */
     @Override public int hashCode() {
-        int result = key != null ? key.hashCode() : 0;
-
-        result = 31 * result + (entry != null ? entry.hashCode() : 0);
+        int res = key != null ? key.hashCode() : 0;
+        res = 31 * res + (entry != null ? entry.hashCode() : 0);
+        res = 31 * res + (tenantId != null ? tenantId.hashCode() : 0);
+        return res;
+    }
 
-        return result;
+    /** {@inheritDoc} */
+    @Override public String toString() {
+        return S.toString(HibernateKeyWrapper.class, this);
     }
 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/7102d532/modules/hibernate/src/main/java/org/apache/ignite/cache/hibernate/HibernateRegionFactory.java
----------------------------------------------------------------------
diff --git 
a/modules/hibernate/src/main/java/org/apache/ignite/cache/hibernate/HibernateRegionFactory.java
 
b/modules/hibernate/src/main/java/org/apache/ignite/cache/hibernate/HibernateRegionFactory.java
index c23d6e5..263359b 100644
--- 
a/modules/hibernate/src/main/java/org/apache/ignite/cache/hibernate/HibernateRegionFactory.java
+++ 
b/modules/hibernate/src/main/java/org/apache/ignite/cache/hibernate/HibernateRegionFactory.java
@@ -117,7 +117,8 @@ public class HibernateRegionFactory implements 
RegionFactory {
 
                 return new HibernateKeyWrapper(
                     cacheKey.getKey(),
-                    cacheKey.getEntityOrRoleName()
+                    cacheKey.getEntityOrRoleName(),
+                    cacheKey.getTenantId()
                 );
             }
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/7102d532/modules/hibernate/src/test/java/org/apache/ignite/cache/hibernate/HibernateL2CacheSelfTest.java
----------------------------------------------------------------------
diff --git 
a/modules/hibernate/src/test/java/org/apache/ignite/cache/hibernate/HibernateL2CacheSelfTest.java
 
b/modules/hibernate/src/test/java/org/apache/ignite/cache/hibernate/HibernateL2CacheSelfTest.java
index a36a823..13956dc 100644
--- 
a/modules/hibernate/src/test/java/org/apache/ignite/cache/hibernate/HibernateL2CacheSelfTest.java
+++ 
b/modules/hibernate/src/test/java/org/apache/ignite/cache/hibernate/HibernateL2CacheSelfTest.java
@@ -479,7 +479,7 @@ public class HibernateL2CacheSelfTest extends 
GridCommonAbstractTest {
      * @param igniteInstanceName Ignite instance name.
      * @return Hibernate configuration.
      */
-    protected Configuration hibernateConfiguration(AccessType accessType,
+    private Configuration hibernateConfiguration(AccessType accessType,
         String igniteInstanceName) {
         Configuration cfg = new Configuration();
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/7102d532/modules/hibernate5/README.txt
----------------------------------------------------------------------
diff --git a/modules/hibernate5/README.txt b/modules/hibernate5/README.txt
new file mode 100644
index 0000000..370258b
--- /dev/null
+++ b/modules/hibernate5/README.txt
@@ -0,0 +1,48 @@
+Apache Ignite Hibernate Module
+------------------------------
+
+Apache Ignite Hibernate module provides Hibernate second-level cache (L2 
cache) implementation based
+on Apache Ignite In-Memory Data Grid.
+
+To enable Hibernate module when starting a standalone node, move 
'optional/ignite-hibernate5' folder to
+'libs' folder before running 'ignite.{sh|bat}' script. The content of the 
module folder will
+be added to classpath in this case.
+
+Importing Hibernate Module In Maven Project
+-------------------------------------------
+
+If you are using Maven to manage dependencies of your project, you can add 
Hibernate module
+dependency like this (replace '${ignite.version}' with actual Ignite version 
you are
+interested in):
+
+<project xmlns="http://maven.apache.org/POM/4.0.0";
+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
+    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
+                        http://maven.apache.org/xsd/maven-4.0.0.xsd";>
+    ...
+    <dependencies>
+        ...
+        <dependency>
+            <groupId>org.apache.ignite</groupId>
+            <artifactId>ignite-hibernate5</artifactId>
+            <version>${ignite.version}</version>
+        </dependency>
+        ...
+    </dependencies>
+    ...
+</project>
+
+
+LGPL dependencies
+-----------------
+
+Ignite includes the following optional LGPL dependencies:
+ - Hibernate L2 Cache Integration, http://hibernate.org/orm/
+ - JTS Topology Suite for Geospatial indexing, 
http://tsusiatsoftware.net/jts/main.html
+ - cron4j for cron-based task scheduling, 
http://www.sauronsoftware.it/projects/cron4j
+
+Apache binary releases cannot include LGPL dependencies. If you would like 
include
+optional LGPL dependencies into your release, you should download the source 
release
+from Ignite website and do the build with the following maven command:
+
+mvn clean package -DskipTests -Prelease,lgpl

http://git-wip-us.apache.org/repos/asf/ignite/blob/7102d532/modules/hibernate5/licenses/apache-2.0.txt
----------------------------------------------------------------------
diff --git a/modules/hibernate5/licenses/apache-2.0.txt 
b/modules/hibernate5/licenses/apache-2.0.txt
new file mode 100644
index 0000000..d645695
--- /dev/null
+++ b/modules/hibernate5/licenses/apache-2.0.txt
@@ -0,0 +1,202 @@
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed 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.

http://git-wip-us.apache.org/repos/asf/ignite/blob/7102d532/modules/hibernate5/pom.xml
----------------------------------------------------------------------
diff --git a/modules/hibernate5/pom.xml b/modules/hibernate5/pom.xml
new file mode 100644
index 0000000..13a0c40
--- /dev/null
+++ b/modules/hibernate5/pom.xml
@@ -0,0 +1,146 @@
+<?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.
+-->
+
+<!--
+    POM file.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0"; 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"; 
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
http://maven.apache.org/xsd/maven-4.0.0.xsd";>
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.apache.ignite</groupId>
+        <artifactId>ignite-parent</artifactId>
+        <version>1</version>
+        <relativePath>../../parent</relativePath>
+    </parent>
+
+    <artifactId>ignite-hibernate5</artifactId>
+    <version>2.0.0-SNAPSHOT</version>
+    <url>http://ignite.apache.org</url>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.ignite</groupId>
+            <artifactId>ignite-core</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.hibernate</groupId>
+            <artifactId>hibernate-core</artifactId>
+            <version>5.2.9.Final</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.ignite</groupId>
+            <artifactId>ignite-jta</artifactId>
+            <version>${project.version}</version>
+            <scope>test</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>org.ow2.jotm</groupId>
+            <artifactId>jotm-core</artifactId>
+            <version>2.1.9</version>
+            <scope>test</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>commons-dbcp</groupId>
+            <artifactId>commons-dbcp</artifactId>
+            <version>1.4</version>
+            <scope>test</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>com.h2database</groupId>
+            <artifactId>h2</artifactId>
+            <version>${h2.version}</version>
+            <scope>test</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>javax.resource</groupId>
+            <artifactId>connector-api</artifactId>
+            <version>1.5</version>
+            <scope>test</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.ignite</groupId>
+            <artifactId>ignite-core</artifactId>
+            <version>${project.version}</version>
+            <type>test-jar</type>
+            <scope>test</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.ignite</groupId>
+            <artifactId>ignite-spring</artifactId>
+            <version>${project.version}</version>
+            <scope>test</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.ignite</groupId>
+            <artifactId>ignite-log4j</artifactId>
+            <version>${project.version}</version>
+            <scope>test</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>org.springframework</groupId>
+            <artifactId>spring-beans</artifactId>
+            <version>${spring.version}</version>
+            <scope>test</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>org.springframework</groupId>
+            <artifactId>spring-context</artifactId>
+            <version>${spring.version}</version>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <testResources>
+            <testResource>
+                <directory>src/main/java</directory>
+                <excludes>
+                    <exclude>**/*.java</exclude>
+                </excludes>
+            </testResource>
+            <testResource>
+                <directory>src/test/java</directory>
+                <excludes>
+                    <exclude>**/*.java</exclude>
+                </excludes>
+            </testResource>
+        </testResources>
+
+        <plugins>
+            <!-- Generate the OSGi MANIFEST.MF for this bundle. -->
+            <plugin>
+                <groupId>org.apache.felix</groupId>
+                <artifactId>maven-bundle-plugin</artifactId>
+            </plugin>
+        </plugins>
+    </build>
+</project>

http://git-wip-us.apache.org/repos/asf/ignite/blob/7102d532/modules/hibernate5/src/main/java/org/apache/ignite/cache/hibernate/HibernateAbstractRegionAccessStrategy.java
----------------------------------------------------------------------
diff --git 
a/modules/hibernate5/src/main/java/org/apache/ignite/cache/hibernate/HibernateAbstractRegionAccessStrategy.java
 
b/modules/hibernate5/src/main/java/org/apache/ignite/cache/hibernate/HibernateAbstractRegionAccessStrategy.java
new file mode 100644
index 0000000..efb9056
--- /dev/null
+++ 
b/modules/hibernate5/src/main/java/org/apache/ignite/cache/hibernate/HibernateAbstractRegionAccessStrategy.java
@@ -0,0 +1,99 @@
+/*
+ * 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 org.hibernate.cache.CacheException;
+import org.hibernate.cache.spi.access.RegionAccessStrategy;
+import org.hibernate.cache.spi.access.SoftLock;
+import org.hibernate.engine.spi.SharedSessionContractImplementor;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * Implementation of L2 cache access strategy delegating to {@link 
HibernateAccessStrategyAdapter}.
+ */
+public abstract class HibernateAbstractRegionAccessStrategy implements 
RegionAccessStrategy {
+    /** */
+    protected final HibernateAccessStrategyAdapter stgy;
+
+    /**
+     * @param stgy Access strategy implementation.
+     */
+    protected 
HibernateAbstractRegionAccessStrategy(HibernateAccessStrategyAdapter stgy) {
+        this.stgy = stgy;
+    }
+
+    /** {@inheritDoc} */
+    @Nullable @Override public Object get(SharedSessionContractImplementor 
ses, Object key, long txTs) throws CacheException {
+        return stgy.get(key);
+    }
+
+    /** {@inheritDoc} */
+    @Override public boolean putFromLoad(SharedSessionContractImplementor ses, 
Object key, Object val, long txTs, Object ver) throws CacheException {
+        stgy.putFromLoad(key, val);
+
+        return true;
+    }
+
+    /** {@inheritDoc} */
+    @Override public boolean putFromLoad(SharedSessionContractImplementor ses, 
Object key, Object val, long txTs, Object ver, boolean minimalPutOverride)
+        throws CacheException {
+        stgy.putFromLoad(key, val, minimalPutOverride);
+
+        return true;
+    }
+
+    /** {@inheritDoc} */
+    @Nullable @Override public SoftLock 
lockItem(SharedSessionContractImplementor ses, Object key, Object ver) throws 
CacheException {
+        return stgy.lock(key);
+    }
+
+    /** {@inheritDoc} */
+    @Nullable @Override public SoftLock lockRegion() throws CacheException {
+        return stgy.lockRegion();
+    }
+
+    /** {@inheritDoc} */
+    @Override public void unlockRegion(SoftLock lock) throws CacheException {
+        stgy.unlockRegion(lock);
+    }
+
+    /** {@inheritDoc} */
+    @Override public void unlockItem(SharedSessionContractImplementor ses, 
Object key, SoftLock lock) throws CacheException {
+        stgy.unlock(key, lock);
+    }
+
+    /** {@inheritDoc} */
+    @Override public void remove(SharedSessionContractImplementor ses, Object 
key) throws CacheException {
+        stgy.remove(key);
+    }
+
+    /** {@inheritDoc} */
+    @Override public void removeAll() throws CacheException {
+        stgy.removeAll();
+    }
+
+    /** {@inheritDoc} */
+    @Override public void evict(Object key) throws CacheException {
+        stgy.evict(key);
+    }
+
+    /** {@inheritDoc} */
+    @Override public void evictAll() throws CacheException {
+        stgy.evictAll();
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ignite/blob/7102d532/modules/hibernate5/src/main/java/org/apache/ignite/cache/hibernate/HibernateAccessStrategyAdapter.java
----------------------------------------------------------------------
diff --git 
a/modules/hibernate5/src/main/java/org/apache/ignite/cache/hibernate/HibernateAccessStrategyAdapter.java
 
b/modules/hibernate5/src/main/java/org/apache/ignite/cache/hibernate/HibernateAccessStrategyAdapter.java
new file mode 100644
index 0000000..f6c1d0e
--- /dev/null
+++ 
b/modules/hibernate5/src/main/java/org/apache/ignite/cache/hibernate/HibernateAccessStrategyAdapter.java
@@ -0,0 +1,379 @@
+/*
+ * 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.io.Externalizable;
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+import org.apache.ignite.Ignite;
+import org.apache.ignite.IgniteCheckedException;
+import org.apache.ignite.IgniteException;
+import org.apache.ignite.IgniteLogger;
+import org.apache.ignite.internal.IgniteKernal;
+import org.apache.ignite.internal.processors.cache.IgniteInternalCache;
+import org.apache.ignite.internal.util.typedef.internal.U;
+import org.apache.ignite.lang.IgniteCallable;
+import org.apache.ignite.resources.IgniteInstanceResource;
+import org.hibernate.cache.CacheException;
+import org.hibernate.cache.spi.access.CollectionRegionAccessStrategy;
+import org.hibernate.cache.spi.access.EntityRegionAccessStrategy;
+import org.hibernate.cache.spi.access.NaturalIdRegionAccessStrategy;
+import org.hibernate.cache.spi.access.RegionAccessStrategy;
+import org.hibernate.cache.spi.access.SoftLock;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * Common interface used to implement Hibernate L2 cache access strategies 
({@link RegionAccessStrategy},
+ * {@link EntityRegionAccessStrategy} and {@link 
CollectionRegionAccessStrategy}).
+ * <p>
+ * The expected sequences of steps related to various CRUD operations executed 
by Hibernate are:
+ * <p>
+ * Insert:
+ * <ul>
+ *     <li>Start DB transaction.</li>
+ *     <li>Execute database insert.</li>
+ *     <li>Call {@link HibernateAccessStrategyAdapter#insert}.</li>
+ *     <li>Commit DB transaction.</li>
+ *     <li>Call {@link HibernateAccessStrategyAdapter#afterInsert}.</li>
+ * </ul>
+ * In case if some step fails and DB transaction is rolled back then
+ * {@link HibernateAccessStrategyAdapter#afterInsert} is not called.
+ * <p>
+ * Update:
+ * <ul>
+ *     <li>Start DB transaction.</li>
+ *     <li>Call {@link HibernateAccessStrategyAdapter#lock}.</li>
+ *     <li>Execute database update.</li>
+ *     <li>Call {@link HibernateAccessStrategyAdapter#update}.</li>
+ *     <li>Commit DB transaction.</li>
+ *     <li>Call {@link HibernateAccessStrategyAdapter#afterUpdate}.</li>
+ * </ul>
+ * In case if {@link HibernateAccessStrategyAdapter#lock} was called, but some 
other step fails and DB
+ * transaction is rolled back then {@link 
HibernateAccessStrategyAdapter#unlock} is called for all locked keys.
+ * <p>
+ * Delete:
+ * <ul>
+ *     <li>Start DB transaction.</li>
+ *     <li>Call {@link HibernateAccessStrategyAdapter#lock} for removing 
key.</li>
+ *     <li>Execute database delete.</li>
+ *     <li>Call {@link HibernateAccessStrategyAdapter#remove}.</li>
+ *     <li>Commit DB transaction.</li>
+ *     <li>Call {@link HibernateAccessStrategyAdapter#unlock}.</li>
+ * </ul>
+ * In case if {@link HibernateAccessStrategyAdapter#lock} was called, but some 
other step fails and DB
+ * transaction is rolled back then {@link 
HibernateAccessStrategyAdapter#unlock} is called for all locked keys.
+ * <p>
+ * In case if custom SQL update query is executed Hibernate clears entire 
cache region,
+ * for this case operations sequence is:
+ * <ul>
+ *     <li>Start DB transaction.</li>
+ *     <li>Call {@link HibernateAccessStrategyAdapter#lockRegion}.</li>
+ *     <li>Execute database query.</li>
+ *     <li>Call {@link HibernateAccessStrategyAdapter#removeAll}.</li>
+ *     <li>Commit DB transaction.</li>
+ *     <li>Call {@link HibernateAccessStrategyAdapter#unlockRegion}.</li>
+ * </ul>
+ */
+public abstract class HibernateAccessStrategyAdapter {
+    /** */
+    protected final HibernateCacheProxy cache;
+
+    /** Grid. */
+    protected final Ignite ignite;
+
+    /** */
+    protected final IgniteLogger log;
+
+    /**
+     * @param ignite Grid.
+     * @param cache Cache.
+     */
+    protected HibernateAccessStrategyAdapter(Ignite ignite, 
HibernateCacheProxy cache) {
+        this.cache = cache;
+        this.ignite = ignite;
+
+        log = ignite.log();
+    }
+
+    /**
+     * Gets value from cache. Used by {@link RegionAccessStrategy#get}.
+     *
+     * @param key Key.
+     * @return Cached value.
+     * @throws CacheException If failed.
+     */
+    @Nullable protected Object get(Object key) throws CacheException {
+        try {
+            return cache.get(key);
+        }
+        catch (IgniteCheckedException e) {
+            throw new CacheException(e);
+        }
+    }
+
+    /**
+     * Puts in cache value loaded from the database. Used by {@link 
RegionAccessStrategy#putFromLoad}.
+     *
+     * @param key Key.
+     * @param val Value.
+     * @param minimalPutOverride MinimalPut flag
+     * @throws CacheException If failed.
+     */
+    protected void putFromLoad(Object key, Object val, boolean 
minimalPutOverride) throws CacheException {
+        putFromLoad(key, val);
+    }
+
+    /**
+     * Puts in cache value loaded from the database. Used by {@link 
RegionAccessStrategy#putFromLoad}.
+     *
+     * @param key Key.
+     * @param val Value.
+     * @throws CacheException If failed.
+     */
+    protected void putFromLoad(Object key, Object val) throws CacheException {
+        try {
+            cache.put(key, val);
+        }
+        catch (IgniteCheckedException e) {
+            throw new CacheException(e);
+        }
+    }
+
+    /**
+     * Called during database transaction execution before Hibernate attempts 
to update or remove given key.
+     * Used by {@link RegionAccessStrategy#lockItem}.
+     *
+     * @param key Key.
+     * @return Lock representation or {@code null}.
+     * @throws CacheException If failed.
+     */
+    @Nullable protected abstract SoftLock lock(Object key) throws 
CacheException;
+
+    /**
+     * Called after Hibernate failed to update or successfully removed given 
key.
+     * Used by {@link RegionAccessStrategy#unlockItem}.
+     *
+     * @param key Key.
+     * @param lock The lock previously obtained from {@link #lock}
+     * @throws CacheException If failed.
+     */
+    protected abstract void unlock(Object key, SoftLock lock) throws 
CacheException;
+
+    /**
+     * Called after Hibernate updated object in the database but before 
transaction completed.
+     * Used by {@link EntityRegionAccessStrategy#update} and {@link 
NaturalIdRegionAccessStrategy#update}.
+     *
+     * @param key Key.
+     * @param val Value.
+     * @return {@code True} if operation updated cache.
+     * @throws CacheException If failed.
+     */
+    protected abstract boolean update(Object key, Object val) throws 
CacheException;
+
+    /**
+     * Called after Hibernate updated object in the database and transaction 
successfully completed.
+     * Used by {@link EntityRegionAccessStrategy#afterUpdate} and {@link 
NaturalIdRegionAccessStrategy#afterUpdate}.
+     *
+     * @param key Key.
+     * @param val Value.
+     * @param lock The lock previously obtained from {@link #lock}
+     * @return {@code True} if operation updated cache.
+     * @throws CacheException If failed.
+     */
+    protected abstract boolean afterUpdate(Object key, Object val, SoftLock 
lock) throws CacheException;
+
+    /**
+     * Called after Hibernate inserted object in the database but before 
transaction completed.
+     * Used by {@link EntityRegionAccessStrategy#insert} and {@link 
NaturalIdRegionAccessStrategy#insert}.
+     *
+     * @param key Key.
+     * @param val Value.
+     * @return {@code True} if operation updated cache.
+     * @throws CacheException If failed.
+     */
+    protected abstract boolean insert(Object key, Object val) throws 
CacheException;
+
+    /**
+     * Called after Hibernate inserted object in the database and transaction 
successfully completed.
+     * Used by {@link EntityRegionAccessStrategy#afterInsert} and {@link 
NaturalIdRegionAccessStrategy#afterInsert}.
+     *
+     * @param key Key.
+     * @param val Value.
+     * @return {@code True} if operation updated cache.
+     * @throws CacheException If failed.
+     */
+    protected abstract boolean afterInsert(Object key, Object val) throws 
CacheException;
+
+    /**
+     * Called after Hibernate removed object from database but before 
transaction completed.
+     * Used by {@link RegionAccessStrategy#remove}.
+     *
+     * @param key Key,
+     * @throws CacheException If failed.
+     */
+    protected abstract void remove(Object key) throws CacheException;
+
+    /**
+     * Called to remove object from cache without regard to transaction.
+     * Used by {@link RegionAccessStrategy#evict}.
+     *
+     * @param key Key.
+     * @throws CacheException If failed.
+     */
+    protected void evict(Object key) throws CacheException {
+        evict(ignite, cache, key);
+    }
+
+    /**
+     * Called to remove all data from cache without regard to transaction.
+     * Used by {@link RegionAccessStrategy#evictAll}.
+     *
+     * @throws CacheException If failed.
+     */
+    protected void evictAll() throws CacheException {
+        evictAll(cache);
+    }
+
+    /**
+     * Called during database transaction execution before Hibernate executed
+     * update operation which should invalidate entire cache region.
+     * Used by {@link RegionAccessStrategy#lockRegion}.
+     *
+     * @throws CacheException If failed.
+     * @return Lock representation or {@code null}.
+     */
+    @Nullable protected SoftLock lockRegion() throws CacheException {
+        return null;
+    }
+
+    /**
+     * Called after transaction clearing entire cache region completed.
+     * Used by {@link RegionAccessStrategy#unlockRegion}.
+     *
+     * @param lock The lock previously obtained from {@link #lockRegion}
+     * @throws CacheException If failed.
+     */
+    protected void unlockRegion(SoftLock lock) throws CacheException {
+        // No-op.
+    }
+
+    /**
+     * Called during database transaction execution to clear entire cache 
region after
+     * Hibernate executed database update, but before transaction completed.
+     * Used by {@link RegionAccessStrategy#removeAll}.
+     *
+     * @throws CacheException If failed.
+     */
+    protected final void removeAll() throws CacheException {
+        evictAll();
+    }
+
+    /**
+     * Called to remove object from cache without regard to transaction.
+     *
+     * @param ignite Grid.
+     * @param cache Cache.
+     * @param key Key.
+     * @throws CacheException If failed.
+     */
+    static void evict(Ignite ignite, HibernateCacheProxy cache, Object key) 
throws CacheException {
+        try {
+            key = cache.keyTransformer().transform(key);
+
+            ignite.compute(ignite.cluster()).call(new ClearKeyCallable(key, 
cache.name()));
+        }
+        catch (IgniteException e) {
+            throw new CacheException(e);
+        }
+    }
+
+    /**
+     * Called to remove all data from cache without regard to transaction.
+     *
+     * @param cache Cache.
+     * @throws CacheException If failed.
+     */
+    static void evictAll(IgniteInternalCache<Object,Object> cache) throws 
CacheException {
+        try {
+            cache.clear();
+        }
+        catch (IgniteCheckedException e) {
+            throw new CacheException(e);
+        }
+    }
+
+    /**
+     * Callable invalidates given key.
+     */
+    private static class ClearKeyCallable implements IgniteCallable<Void>, 
Externalizable {
+        /** */
+        private static final long serialVersionUID = 0L;
+
+        /** */
+        @IgniteInstanceResource
+        private Ignite ignite;
+
+        /** */
+        private Object key;
+
+        /** */
+        private String cacheName;
+
+        /**
+         * Empty constructor required by {@link Externalizable}.
+         */
+        public ClearKeyCallable() {
+            // No-op.
+        }
+
+        /**
+         * @param key Key to clear.
+         * @param cacheName Cache name.
+         */
+        private ClearKeyCallable(Object key, String cacheName) {
+            this.key = key;
+            this.cacheName = cacheName;
+        }
+
+        /** {@inheritDoc} */
+        @Override public Void call() throws IgniteCheckedException {
+            IgniteInternalCache<Object, Object> cache = 
((IgniteKernal)ignite).getCache(cacheName);
+
+            assert cache != null;
+
+            cache.clearLocally(key);
+
+            return null;
+        }
+
+        /** {@inheritDoc} */
+        @Override public void writeExternal(ObjectOutput out) throws 
IOException {
+            out.writeObject(key);
+
+            U.writeString(out, cacheName);
+        }
+
+        /** {@inheritDoc} */
+        @Override public void readExternal(ObjectInput in) throws IOException, 
ClassNotFoundException {
+            key = in.readObject();
+
+            cacheName = U.readString(in);
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ignite/blob/7102d532/modules/hibernate5/src/main/java/org/apache/ignite/cache/hibernate/HibernateCacheProxy.java
----------------------------------------------------------------------
diff --git 
a/modules/hibernate5/src/main/java/org/apache/ignite/cache/hibernate/HibernateCacheProxy.java
 
b/modules/hibernate5/src/main/java/org/apache/ignite/cache/hibernate/HibernateCacheProxy.java
new file mode 100644
index 0000000..69d9097
--- /dev/null
+++ 
b/modules/hibernate5/src/main/java/org/apache/ignite/cache/hibernate/HibernateCacheProxy.java
@@ -0,0 +1,811 @@
+/*
+ * 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.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.Map;
+import java.util.Set;
+import java.util.UUID;
+import javax.cache.Cache;
+import javax.cache.expiry.ExpiryPolicy;
+import javax.cache.processor.EntryProcessor;
+import javax.cache.processor.EntryProcessorResult;
+import org.apache.ignite.IgniteCheckedException;
+import org.apache.ignite.cache.CacheEntry;
+import org.apache.ignite.cache.CacheMetrics;
+import org.apache.ignite.cache.CachePeekMode;
+import org.apache.ignite.cache.affinity.Affinity;
+import org.apache.ignite.cluster.ClusterGroup;
+import org.apache.ignite.configuration.CacheConfiguration;
+import org.apache.ignite.internal.IgniteInternalFuture;
+import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion;
+import org.apache.ignite.internal.processors.cache.CacheEntryPredicate;
+import org.apache.ignite.internal.processors.cache.GridCacheContext;
+import org.apache.ignite.internal.processors.cache.IgniteCacheExpiryPolicy;
+import org.apache.ignite.internal.processors.cache.IgniteInternalCache;
+import 
org.apache.ignite.internal.processors.cache.distributed.near.GridNearTxLocal;
+import org.apache.ignite.lang.IgniteBiPredicate;
+import org.apache.ignite.mxbean.CacheMetricsMXBean;
+import org.apache.ignite.transactions.Transaction;
+import org.apache.ignite.transactions.TransactionConcurrency;
+import org.apache.ignite.transactions.TransactionIsolation;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * Hibernate cache proxy.
+ */
+public class HibernateCacheProxy implements IgniteInternalCache<Object, 
Object> {
+    /** Delegate. */
+    private final IgniteInternalCache<Object, Object> delegate;
+
+    /** Transformer. */
+    private final HibernateKeyTransformer keyTransformer;
+
+    /**
+     * @param delegate Delegate.
+     * @param keyTransformer Key keyTransformer.
+     */
+    HibernateCacheProxy(
+        IgniteInternalCache<Object, Object> delegate,
+        HibernateKeyTransformer keyTransformer
+    ) {
+        assert delegate != null;
+        assert keyTransformer != null;
+
+        this.delegate = delegate;
+        this.keyTransformer = keyTransformer;
+    }
+
+    /**
+     * @return HibernateKeyTransformer
+     */
+    HibernateKeyTransformer keyTransformer(){
+        return keyTransformer;
+    }
+
+    /** {@inheritDoc} */
+    @Override public String name() {
+        return delegate.name();
+    }
+
+    /** {@inheritDoc} */
+    @Override public boolean skipStore() {
+        return delegate.skipStore();
+    }
+
+    /** {@inheritDoc} */
+    @Override public IgniteInternalCache setSkipStore(boolean skipStore) {
+        return delegate.setSkipStore(skipStore);
+    }
+
+    /** {@inheritDoc} */
+    @Override public boolean isEmpty() {
+        return delegate.isEmpty();
+    }
+
+    /** {@inheritDoc} */
+    @Override public boolean containsKey(Object key) {
+        return delegate.containsKey(keyTransformer.transform(key));
+    }
+
+    /** {@inheritDoc} */
+    @Override public IgniteInternalFuture<Boolean> containsKeyAsync(Object 
key) {
+        return delegate.containsKeyAsync(keyTransformer.transform(key));
+    }
+
+    /** {@inheritDoc} */
+    @Override public boolean containsKeys(Collection keys) {
+        return delegate.containsKey(transform(keys));
+    }
+
+    /** {@inheritDoc} */
+    @Override public IgniteInternalFuture<Boolean> 
containsKeysAsync(Collection keys) {
+        return delegate.containsKeysAsync(transform(keys));
+    }
+
+    /** {@inheritDoc} */
+    @Nullable @Override public Object localPeek(
+        Object key,
+        CachePeekMode[] peekModes,
+        @Nullable IgniteCacheExpiryPolicy plc
+    ) throws IgniteCheckedException {
+        return delegate.localPeek(keyTransformer.transform(key), peekModes, 
plc);
+    }
+
+    /** {@inheritDoc} */
+    @Override public Iterable<Cache.Entry<Object, Object>> localEntries(
+        CachePeekMode[] peekModes
+    ) throws IgniteCheckedException {
+        return delegate.localEntries(peekModes);
+    }
+
+    /** {@inheritDoc} */
+    @Nullable @Override public Object get(Object key) throws 
IgniteCheckedException {
+        return delegate.get(keyTransformer.transform(key));
+    }
+
+    /** {@inheritDoc} */
+    @Nullable @Override public CacheEntry getEntry(Object key) throws 
IgniteCheckedException {
+        return delegate.getEntry(keyTransformer.transform(key));
+    }
+
+    /** {@inheritDoc} */
+    @Override public IgniteInternalFuture getAsync(Object key) {
+        return delegate.getAsync(keyTransformer.transform(key));
+    }
+
+    /** {@inheritDoc} */
+    @Override public IgniteInternalFuture<CacheEntry<Object, Object>> 
getEntryAsync(Object key) {
+        return delegate.getEntryAsync(keyTransformer.transform(key));
+    }
+
+    /** {@inheritDoc} */
+    @Override public Map getAll(@Nullable Collection keys) throws 
IgniteCheckedException {
+        return delegate.getAll(transform(keys));
+    }
+
+    /** {@inheritDoc} */
+    @Override public Collection<CacheEntry<Object, Object>> getEntries(
+        @Nullable Collection keys) throws IgniteCheckedException {
+        return delegate.getEntries(transform(keys));
+    }
+
+    /** {@inheritDoc} */
+    @Override public IgniteInternalFuture<Map<Object, Object>> 
getAllAsync(@Nullable Collection keys) {
+        return delegate.getAllAsync(transform(keys));
+    }
+
+    /** {@inheritDoc} */
+    @Override public 
IgniteInternalFuture<Collection<CacheEntry<Object,Object>>> getEntriesAsync(
+        @Nullable Collection keys
+    ) {
+        return delegate.getEntriesAsync(transform(keys));
+    }
+
+    /** {@inheritDoc} */
+    @Nullable @Override public Object getAndPut(Object key, Object val) throws 
IgniteCheckedException {
+        return delegate.getAndPut(keyTransformer.transform(key), val);
+    }
+
+    /** {@inheritDoc} */
+    @Override public IgniteInternalFuture getAndPutAsync(Object key, Object 
val) {
+        return delegate.getAndPutAsync(keyTransformer.transform(key), val);
+    }
+
+    /** {@inheritDoc} */
+    @Override public boolean put(Object key, Object val) throws 
IgniteCheckedException {
+        return delegate.put(keyTransformer.transform(key), val);
+    }
+
+    /** {@inheritDoc} */
+    @Override public IgniteInternalFuture<Boolean> putAsync(Object key, Object 
val) {
+        return delegate.putAsync(keyTransformer.transform(key), val);
+    }
+
+    /** {@inheritDoc} */
+    @Nullable @Override public Object getAndPutIfAbsent(Object key, Object 
val) throws IgniteCheckedException {
+        return delegate.getAndPutIfAbsent(keyTransformer.transform(key), val);
+    }
+
+    /** {@inheritDoc} */
+    @Override public IgniteInternalFuture getAndPutIfAbsentAsync(Object key, 
Object val) {
+        return delegate.getAndPutIfAbsentAsync(keyTransformer.transform(key), 
val);
+    }
+
+    /** {@inheritDoc} */
+    @Override public boolean putIfAbsent(Object key, Object val) throws 
IgniteCheckedException {
+        return delegate.putIfAbsent(keyTransformer.transform(key), val);
+    }
+
+    /** {@inheritDoc} */
+    @Override public IgniteInternalFuture<Boolean> putIfAbsentAsync(Object 
key, Object val) {
+        return delegate.putIfAbsentAsync(keyTransformer.transform(key), val);
+    }
+
+    /** {@inheritDoc} */
+    @Nullable @Override public Object getAndReplace(Object key, Object val) 
throws IgniteCheckedException {
+        return delegate.getAndReplace(keyTransformer.transform(key), val);
+    }
+
+    /** {@inheritDoc} */
+    @Override public IgniteInternalFuture getAndReplaceAsync(Object key, 
Object val) {
+        return delegate.getAndReplaceAsync(keyTransformer.transform(key), val);
+    }
+
+    /** {@inheritDoc} */
+    @Override public boolean replace(Object key, Object val) throws 
IgniteCheckedException {
+        return delegate.replace(keyTransformer.transform(key), val);
+    }
+
+    /** {@inheritDoc} */
+    @Override public IgniteInternalFuture<Boolean> replaceAsync(Object key, 
Object val) {
+        return delegate.replaceAsync(keyTransformer.transform(key), val);
+    }
+
+    /** {@inheritDoc} */
+    @Override public boolean replace(Object key, Object oldVal, Object newVal) 
throws IgniteCheckedException {
+        return delegate.replace(keyTransformer.transform(key), oldVal, newVal);
+    }
+
+    /** {@inheritDoc} */
+    @Override public IgniteInternalFuture<Boolean> replaceAsync(Object key, 
Object oldVal, Object newVal) {
+        return delegate.replaceAsync(keyTransformer.transform(key), oldVal, 
newVal);
+    }
+
+    /** {@inheritDoc} */
+    @Override public void putAll(@Nullable Map m) throws 
IgniteCheckedException {
+        delegate.putAll(transform(m));
+    }
+
+    /** {@inheritDoc} */
+    @Override public IgniteInternalFuture<?> putAllAsync(@Nullable Map m) {
+        return delegate.putAllAsync(transform(m));
+    }
+
+    /** {@inheritDoc} */
+    @Override public Set keySet() {
+        return delegate.keySet();
+    }
+
+    /** {@inheritDoc} */
+    @Override public Set keySetx() {
+        return delegate.keySetx();
+    }
+
+    /** {@inheritDoc} */
+    @Override public Set primaryKeySet() {
+        return delegate.primaryKeySet();
+    }
+
+    /** {@inheritDoc} */
+    @Override public Iterable values() {
+        return delegate.values();
+    }
+
+    /** {@inheritDoc} */
+    @Override public Set<Cache.Entry<Object, Object>> entrySet() {
+        return delegate.entrySet();
+    }
+
+    /** {@inheritDoc} */
+    @Nullable @Override public Set<Cache.Entry<Object,Object>> entrySet(int 
part) {
+        return delegate.entrySet(part);
+    }
+
+    /** {@inheritDoc} */
+    @Override public Set<Cache.Entry<Object, Object>> 
entrySetx(CacheEntryPredicate... filter) {
+        return delegate.entrySetx(filter);
+    }
+
+    /** {@inheritDoc} */
+    @Override public Transaction txStart(
+        TransactionConcurrency concurrency,
+        TransactionIsolation isolation
+    ) {
+        return delegate.txStart(concurrency, isolation);
+    }
+
+    /** {@inheritDoc} */
+    @Override public GridNearTxLocal txStartEx(
+        TransactionConcurrency concurrency,
+        TransactionIsolation isolation
+    ) {
+        return delegate.txStartEx(concurrency, isolation);
+    }
+
+    /** {@inheritDoc} */
+    @Override public Transaction txStart(
+        TransactionConcurrency concurrency,
+        TransactionIsolation isolation,
+        long timeout,
+        int txSize
+    ) {
+        return delegate.txStart(concurrency, isolation, timeout, txSize);
+    }
+
+    /** {@inheritDoc} */
+    @Nullable @Override public GridNearTxLocal tx() {
+        return delegate.tx();
+    }
+
+    /** {@inheritDoc} */
+    @Override public boolean evict(Object key) {
+        return delegate.evict(keyTransformer.transform(key));
+    }
+
+    /** {@inheritDoc} */
+    @Override public void evictAll(@Nullable Collection keys) {
+        delegate.evictAll(transform(keys));
+    }
+
+    /** {@inheritDoc} */
+    @Override public void clearLocally(boolean srv, boolean near, boolean 
readers) {
+        delegate.clearLocally(srv, near, readers);
+    }
+
+    /** {@inheritDoc} */
+    @Override public boolean clearLocally(Object key) {
+        return delegate.clearLocally(keyTransformer.transform(key));
+    }
+
+    /** {@inheritDoc} */
+    @Override public void clearLocallyAll(Set keys, boolean srv, boolean near, 
boolean readers) {
+        delegate.clearLocallyAll((Set<?>)transform(keys), srv, near, readers);
+    }
+
+    /** {@inheritDoc} */
+    @Override public void clear(Object key) throws IgniteCheckedException {
+        delegate.clear(keyTransformer.transform(key));
+    }
+
+    /** {@inheritDoc} */
+    @Override public void clearAll(Set keys) throws IgniteCheckedException {
+        delegate.clearAll((Set<?>)transform(keys));
+    }
+
+    /** {@inheritDoc} */
+    @Override public void clear() throws IgniteCheckedException {
+        delegate.clear();
+    }
+
+    /** {@inheritDoc} */
+    @Override public IgniteInternalFuture<?> clearAsync() {
+        return delegate.clearAsync();
+    }
+
+    /** {@inheritDoc} */
+    @Override public IgniteInternalFuture<?> clearAsync(Object key) {
+        return delegate.clearAsync(keyTransformer.transform(key));
+    }
+
+    /** {@inheritDoc} */
+    @Override public IgniteInternalFuture<?> clearAllAsync(Set keys) {
+        return delegate.clearAllAsync((Set<?>)transform(keys));
+    }
+
+    /** {@inheritDoc} */
+    @Nullable @Override public Object getAndRemove(Object key) throws 
IgniteCheckedException {
+        return delegate.getAndRemove(keyTransformer.transform(key));
+    }
+
+    /** {@inheritDoc} */
+    @Override public IgniteInternalFuture getAndRemoveAsync(Object key) {
+        return delegate.getAndRemoveAsync(keyTransformer.transform(key));
+    }
+
+    /** {@inheritDoc} */
+    @Override public boolean remove(Object key) throws IgniteCheckedException {
+        return delegate.remove(keyTransformer.transform(key));
+    }
+
+    /** {@inheritDoc} */
+    @Override public IgniteInternalFuture<Boolean> removeAsync(Object key) {
+        return delegate.removeAsync(keyTransformer.transform(key));
+    }
+
+    /** {@inheritDoc} */
+    @Override public boolean remove(Object key, Object val) throws 
IgniteCheckedException {
+        return delegate.remove(keyTransformer.transform(key), val);
+    }
+
+    /** {@inheritDoc} */
+    @Override public IgniteInternalFuture<Boolean> removeAsync(Object key, 
Object val) {
+        return delegate.removeAsync(keyTransformer.transform(key), val);
+    }
+
+    /** {@inheritDoc} */
+    @Override public void removeAll(@Nullable Collection keys) throws 
IgniteCheckedException {
+        delegate.removeAll(transform(keys));
+    }
+
+    /** {@inheritDoc} */
+    @Override public IgniteInternalFuture<?> removeAllAsync(@Nullable 
Collection keys) {
+        return delegate.removeAllAsync(transform(keys));
+    }
+
+    /** {@inheritDoc} */
+    @Override public void removeAll() throws IgniteCheckedException {
+        delegate.removeAll();
+    }
+
+    /** {@inheritDoc} */
+    @Override public IgniteInternalFuture<?> removeAllAsync() {
+        return delegate.removeAllAsync();
+    }
+
+    /** {@inheritDoc} */
+    @Override public boolean lock(Object key, long timeout) throws 
IgniteCheckedException {
+        return delegate.lock(keyTransformer.transform(key), timeout);
+    }
+
+    /** {@inheritDoc} */
+    @Override public IgniteInternalFuture<Boolean> lockAsync(Object key, long 
timeout) {
+        return delegate.lockAsync(keyTransformer.transform(key), timeout);
+    }
+
+    /** {@inheritDoc} */
+    @Override public boolean lockAll(@Nullable Collection keys, long timeout) 
throws IgniteCheckedException {
+        return delegate.lockAll(transform(keys), timeout);
+    }
+
+    /** {@inheritDoc} */
+    @Override public IgniteInternalFuture<Boolean> lockAllAsync(@Nullable 
Collection keys, long timeout) {
+        return delegate.lockAllAsync(transform(keys), timeout);
+    }
+
+    /** {@inheritDoc} */
+    @Override public void unlock(Object key) throws IgniteCheckedException {
+        delegate.unlock(keyTransformer.transform(key));
+    }
+
+    /** {@inheritDoc} */
+    @Override public void unlockAll(@Nullable Collection keys) throws 
IgniteCheckedException {
+        delegate.unlockAll(transform(keys));
+    }
+
+    /** {@inheritDoc} */
+    @Override public boolean isLocked(Object key) {
+        return delegate.isLocked(keyTransformer.transform(key));
+    }
+
+    /** {@inheritDoc} */
+    @Override public boolean isLockedByThread(Object key) {
+        return delegate.isLockedByThread(keyTransformer.transform(key));
+    }
+
+    /** {@inheritDoc} */
+    @Override public int size() {
+        return delegate.size();
+    }
+
+    /** {@inheritDoc} */
+    @Override public long sizeLong() {
+        return delegate.sizeLong();
+    }
+
+    /** {@inheritDoc} */
+    @Override public int localSize(CachePeekMode[] peekModes) throws 
IgniteCheckedException {
+        return delegate.localSize(peekModes);
+    }
+
+    /** {@inheritDoc} */
+    @Override public long localSizeLong(CachePeekMode[] peekModes) throws 
IgniteCheckedException {
+        return delegate.localSizeLong(peekModes);
+    }
+
+    /** {@inheritDoc} */
+    @Override public long localSizeLong(int partition, CachePeekMode[] 
peekModes) throws IgniteCheckedException {
+        return delegate.localSizeLong(partition, peekModes);
+    }
+
+    /** {@inheritDoc} */
+    @Override public int size(CachePeekMode[] peekModes) throws 
IgniteCheckedException {
+        return delegate.size(peekModes);
+    }
+
+    /** {@inheritDoc} */
+    @Override public long sizeLong(CachePeekMode[] peekModes) throws 
IgniteCheckedException {
+        return delegate.sizeLong(peekModes);
+    }
+
+    /** {@inheritDoc} */
+    @Override public long sizeLong(int partition, CachePeekMode[] peekModes) 
throws IgniteCheckedException {
+        return delegate.sizeLong(partition, peekModes);
+    }
+
+    /** {@inheritDoc} */
+    @Override public IgniteInternalFuture<Integer> sizeAsync(CachePeekMode[] 
peekModes) {
+        return delegate.sizeAsync(peekModes);
+    }
+
+    /** {@inheritDoc} */
+    @Override public IgniteInternalFuture<Long> sizeLongAsync(CachePeekMode[] 
peekModes) {
+        return delegate.sizeLongAsync(peekModes);
+    }
+
+    /** {@inheritDoc} */
+    @Override public IgniteInternalFuture<Long> sizeLongAsync(int partition, 
CachePeekMode[] peekModes) {
+        return delegate.sizeLongAsync(partition, peekModes);
+    }
+
+    /** {@inheritDoc} */
+    @Override public int nearSize() {
+        return delegate.nearSize();
+    }
+
+    /** {@inheritDoc} */
+    @Override public int primarySize() {
+        return delegate.primarySize();
+    }
+
+    /** {@inheritDoc} */
+    @Override public long primarySizeLong() {
+        return delegate.primarySizeLong();
+    }
+
+    /** {@inheritDoc} */
+    @Override public CacheConfiguration configuration() {
+        return delegate.configuration();
+    }
+
+    /** {@inheritDoc} */
+    @Override public Affinity affinity() {
+        return delegate.affinity();
+    }
+
+    /** {@inheritDoc} */
+    @Override public CacheMetrics clusterMetrics() {
+        return delegate.clusterMetrics();
+    }
+
+    /** {@inheritDoc} */
+    @Override public CacheMetrics clusterMetrics(ClusterGroup grp) {
+        return delegate.clusterMetrics(grp);
+    }
+
+    /** {@inheritDoc} */
+    @Override public CacheMetrics localMetrics() {
+        return delegate.localMetrics();
+    }
+
+    /** {@inheritDoc} */
+    @Override public CacheMetricsMXBean clusterMxBean() {
+        return delegate.clusterMxBean();
+    }
+
+    /** {@inheritDoc} */
+    @Override public CacheMetricsMXBean localMxBean() {
+        return delegate.localMxBean();
+    }
+
+    /** {@inheritDoc} */
+    @Override public long offHeapEntriesCount() {
+        return delegate.offHeapEntriesCount();
+    }
+
+    /** {@inheritDoc} */
+    @Override public long offHeapAllocatedSize() {
+        return delegate.offHeapAllocatedSize();
+    }
+
+    /** {@inheritDoc} */
+    @Override public IgniteInternalFuture<?> rebalance() {
+        return delegate.rebalance();
+    }
+
+    /** {@inheritDoc} */
+    @Override public IgniteInternalCache forSubjectId(UUID subjId) {
+        return delegate.forSubjectId(subjId);
+    }
+
+    /** {@inheritDoc} */
+    @Nullable @Override public Object getForcePrimary(Object key) throws 
IgniteCheckedException {
+        return delegate.getForcePrimary(keyTransformer.transform(key));
+    }
+
+    /** {@inheritDoc} */
+    @Override public IgniteInternalFuture getForcePrimaryAsync(Object key) {
+        return delegate.getForcePrimaryAsync(keyTransformer.transform(key));
+    }
+
+    /** {@inheritDoc} */
+    @Override public Map getAllOutTx(Set keys) throws IgniteCheckedException {
+        return delegate.getAllOutTx((Set<?>)transform(keys));
+    }
+
+    /** {@inheritDoc} */
+    @Override public IgniteInternalFuture<Map<Object, Object>> 
getAllOutTxAsync(Set keys) {
+        return delegate.getAllOutTxAsync((Set<?>)transform(keys));
+    }
+
+    /** {@inheritDoc} */
+    @Override public boolean isIgfsDataCache() {
+        return delegate.isIgfsDataCache();
+    }
+
+    /** {@inheritDoc} */
+    @Override public long igfsDataSpaceUsed() {
+        return delegate.igfsDataSpaceUsed();
+    }
+
+    /** {@inheritDoc} */
+    @Override public long igfsDataSpaceMax() {
+        return delegate.igfsDataSpaceMax();
+    }
+
+    /** {@inheritDoc} */
+    @Override public boolean isMongoDataCache() {
+        return delegate.isMongoDataCache();
+    }
+
+    /** {@inheritDoc} */
+    @Override public boolean isMongoMetaCache() {
+        return delegate.isMongoMetaCache();
+    }
+
+    /** {@inheritDoc} */
+    @Nullable @Override public ExpiryPolicy expiry() {
+        return delegate.expiry();
+    }
+
+    /** {@inheritDoc} */
+    @Override public IgniteInternalCache withExpiryPolicy(ExpiryPolicy plc) {
+        return delegate.withExpiryPolicy(plc);
+    }
+
+    /** {@inheritDoc} */
+    @Override public IgniteInternalCache withNoRetries() {
+        return delegate.withNoRetries();
+    }
+
+    /** {@inheritDoc} */
+    @Override public GridCacheContext context() {
+        return delegate.context();
+    }
+
+    /** {@inheritDoc} */
+    @Override public void localLoadCache(
+        @Nullable IgniteBiPredicate p,
+        @Nullable Object... args
+    ) throws IgniteCheckedException {
+        delegate.localLoadCache(p, args);
+    }
+
+    /** {@inheritDoc} */
+    @Override public IgniteInternalFuture<?> localLoadCacheAsync(
+        @Nullable IgniteBiPredicate p,
+        @Nullable Object... args
+    ) {
+        return delegate.localLoadCacheAsync(p, args);
+    }
+
+    /** {@inheritDoc} */
+    @Override public Object getTopologySafe(Object key) throws 
IgniteCheckedException {
+        return delegate.getTopologySafe(keyTransformer.transform(key));
+    }
+
+    /** {@inheritDoc} */
+    @Nullable @Override public Object tryGetAndPut(Object key, Object val) 
throws IgniteCheckedException {
+        return delegate.tryGetAndPut(keyTransformer.transform(key), val);
+    }
+
+    /** {@inheritDoc} */
+    @Override public Collection<Integer> lostPartitions() {
+        return delegate.lostPartitions();
+    }
+
+    /** {@inheritDoc} */
+    @Nullable @Override public EntryProcessorResult invoke(
+        @Nullable AffinityTopologyVersion topVer,
+        Object key,
+        EntryProcessor entryProcessor,
+        Object... args
+    ) throws IgniteCheckedException {
+        return delegate.invoke(topVer, key, entryProcessor, args);
+    }
+
+    /** {@inheritDoc} */
+    @Override public IgniteInternalFuture<Map> invokeAllAsync(Map map, 
Object... args) {
+        return delegate.invokeAllAsync(map, args);
+    }
+
+    /** {@inheritDoc} */
+    @Override public Map invokeAll(Map map, Object... args) throws 
IgniteCheckedException {
+        return delegate.invokeAll(map, args);
+    }
+
+    /** {@inheritDoc} */
+    @Override public IgniteInternalFuture<Map> invokeAllAsync(Set keys, 
EntryProcessor entryProcessor, Object... args) {
+        return delegate.invokeAllAsync((Set<?>)transform(keys), 
entryProcessor, args);
+    }
+
+    /** {@inheritDoc} */
+    @Override public Map invokeAll(Set keys, EntryProcessor entryProcessor, 
Object... args) throws IgniteCheckedException {
+        return delegate.invokeAll((Set<?>)transform(keys), entryProcessor, 
args);
+    }
+
+    /** {@inheritDoc} */
+    @Override public IgniteInternalFuture<EntryProcessorResult> invokeAsync(
+        Object key,
+        EntryProcessor entryProcessor,
+        Object... args
+    ) {
+        return delegate.invokeAsync(keyTransformer.transform(key), 
entryProcessor, args);
+    }
+
+    /** {@inheritDoc} */
+    @Nullable @Override public EntryProcessorResult invoke(
+        Object key,
+        EntryProcessor entryProcessor,
+        Object... args
+    ) throws IgniteCheckedException {
+        return delegate.invoke(keyTransformer.transform(key), entryProcessor, 
args);
+    }
+
+    /** {@inheritDoc} */
+    @Override public Iterator<Cache.Entry<Object,Object>> scanIterator(
+        boolean keepBinary,
+        @Nullable IgniteBiPredicate p
+    ) throws IgniteCheckedException {
+        return delegate.scanIterator(keepBinary, p);
+    }
+
+    /** {@inheritDoc} */
+    @Override public IgniteInternalFuture<?> removeAllConflictAsync(Map drMap) 
throws IgniteCheckedException {
+        return delegate.removeAllConflictAsync(drMap);
+    }
+
+    /** {@inheritDoc} */
+    @Override public void removeAllConflict(Map drMap) throws 
IgniteCheckedException {
+        delegate.removeAllConflictAsync(drMap);
+    }
+
+    /** {@inheritDoc} */
+    @Override public IgniteInternalFuture<?> putAllConflictAsync(Map drMap) 
throws IgniteCheckedException {
+        return delegate.putAllConflictAsync(drMap);
+    }
+
+    /** {@inheritDoc} */
+    @Override public void putAllConflict(Map drMap) throws 
IgniteCheckedException {
+        delegate.putAllConflict(drMap);
+    }
+
+    /** {@inheritDoc} */
+    @Override public IgniteInternalCache keepBinary() {
+        return delegate.keepBinary();
+    }
+
+    /** {@inheritDoc} */
+    @Override public IgniteInternalCache cache() {
+        return delegate.cache();
+    }
+
+    /** {@inheritDoc} */
+    @Override public Iterator iterator() {
+        return delegate.iterator();
+    }
+
+    /**
+     * @param keys Keys.
+     */
+    private Collection<Object> transform(Collection<Object> keys) {
+        Collection<Object> res = new LinkedList<>();
+
+        for (Object o : keys)
+            res.add(keyTransformer.transform(o));
+
+        return res;
+    }
+
+    /**
+     * @param map Map.
+     */
+    private Map<Object, Object> transform(Map<Object, Object> map) {
+        Map<Object, Object> res = new HashMap<>();
+
+        Set<Map.Entry<Object, Object>> ents = map.entrySet();
+
+        for (Map.Entry<Object, Object> e : ents)
+            res.put(keyTransformer.transform(e.getKey()), e.getValue());
+
+        return res;
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/7102d532/modules/hibernate5/src/main/java/org/apache/ignite/cache/hibernate/HibernateCollectionRegion.java
----------------------------------------------------------------------
diff --git 
a/modules/hibernate5/src/main/java/org/apache/ignite/cache/hibernate/HibernateCollectionRegion.java
 
b/modules/hibernate5/src/main/java/org/apache/ignite/cache/hibernate/HibernateCollectionRegion.java
new file mode 100644
index 0000000..be99e98
--- /dev/null
+++ 
b/modules/hibernate5/src/main/java/org/apache/ignite/cache/hibernate/HibernateCollectionRegion.java
@@ -0,0 +1,114 @@
+/*
+ * 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 org.apache.ignite.Ignite;
+import org.hibernate.cache.CacheException;
+import org.hibernate.cache.spi.CacheDataDescription;
+import org.hibernate.cache.spi.CollectionRegion;
+import org.hibernate.cache.spi.access.AccessType;
+import org.hibernate.cache.spi.access.CollectionRegionAccessStrategy;
+import org.hibernate.engine.spi.SessionFactoryImplementor;
+import org.hibernate.persister.collection.CollectionPersister;
+
+/**
+ * Implementation of {@link CollectionRegion}. This region is used to store 
collection data.
+ * <p>
+ * L2 cache for collection can be enabled in the Hibernate configuration file:
+ * <pre name="code" class="xml">
+ * &lt;hibernate-configuration&gt;
+ *     &lt;!-- Enable L2 cache. --&gt;
+ *     &lt;property 
name="cache.use_second_level_cache"&gt;true&lt;/property&gt;
+ *
+ *     &lt;!-- Use Ignite as L2 cache provider. --&gt;
+ *     &lt;property 
name="cache.region.factory_class"&gt;org.apache.ignite.cache.hibernate.HibernateRegionFactory&lt;/property&gt;
+ *
+ *     &lt;!-- Specify entities. --&gt;
+ *     &lt;mapping class="com.example.Entity"/&gt;
+ *     &lt;mapping class="com.example.ChildEntity"/&gt;
+ *
+ *     &lt;!-- Enable L2 cache with nonstrict-read-write access strategy for 
entities and collection. --&gt;
+ *     &lt;collection-cache collection="com.example.Entity" 
usage="nonstrict-read-write"/&gt;
+ *     &lt;collection-cache collection="com.example.ChildEntity" 
usage="nonstrict-read-write"/&gt;
+ *     &lt;collection-cache collection="com.example.Entity.children" 
usage="nonstrict-read-write"/&gt;
+ * &lt;/hibernate-configuration&gt;
+ * </pre>
+ * Also cache for collection can be enabled using annotations:
+ * <pre name="code" class="java">
+ * &#064;javax.persistence.Entity
+ * public class Entity {
+ *    ...
+ *
+ *    &#064;javax.persistence.OneToMany(cascade=CascadeType.ALL, 
fetch=FetchType.EAGER)
+ *    &#064;javax.persistence.JoinColumn(name="PARENT_ID")
+ *    &#064;org.hibernate.annotations.Cache(usage = 
CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
+ *    public List&lt;ChildEntity&gt; getChildren() {...}
+ * }
+ * </pre>
+ * Note: the collection cache does not cache the state of the actual entities 
in the cache, it caches only identifier
+ * values. For this reason, the collection cache should always be used in 
conjunction with
+ * the second-level cache for those entities expected to be cached as part of 
a collection cache.
+ */
+public class HibernateCollectionRegion extends 
HibernateTransactionalDataRegion implements CollectionRegion {
+    /**
+     * @param factory Region factory.
+     * @param name Region name.
+     * @param ignite Grid.
+     * @param cache Region cache.
+     * @param dataDesc Region data description.
+     */
+    public HibernateCollectionRegion(HibernateRegionFactory factory, String 
name,
+        Ignite ignite, HibernateCacheProxy cache, CacheDataDescription 
dataDesc) {
+        super(factory, name, ignite, cache, dataDesc);
+    }
+
+    /** {@inheritDoc} */
+    @Override public CollectionRegionAccessStrategy 
buildAccessStrategy(AccessType accessType) throws CacheException {
+        return new AccessStrategy(createAccessStrategy(accessType));
+    }
+
+    /**
+     * Collection region access strategy.
+     */
+    private class AccessStrategy extends HibernateAbstractRegionAccessStrategy
+        implements CollectionRegionAccessStrategy {
+        /**
+         * @param stgy Access strategy implementation.
+         */
+        private AccessStrategy(HibernateAccessStrategyAdapter stgy) {
+            super(stgy);
+        }
+
+        /** {@inheritDoc} */
+        @Override public Object generateCacheKey(Object id,
+            CollectionPersister persister,
+            SessionFactoryImplementor factory, String tenantIdentifier) {
+            return HibernateKeyWrapper.staticCreateCollectionKey(id, 
persister, tenantIdentifier);
+        }
+
+        /** {@inheritDoc} */
+        @Override public Object getCacheKeyId(Object cacheKey) {
+            return ((HibernateKeyWrapper)cacheKey).id();
+        }
+
+        /** {@inheritDoc} */
+        @Override public CollectionRegion getRegion() {
+            return HibernateCollectionRegion.this;
+        }
+    }
+}
\ No newline at end of file

Reply via email to