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"> + * <hibernate-configuration> + * <!-- Enable L2 cache. --> + * <property name="cache.use_second_level_cache">true</property> + * + * <!-- Use Ignite as L2 cache provider. --> + * <property name="cache.region.factory_class">org.apache.ignite.cache.hibernate.HibernateRegionFactory</property> + * + * <!-- Specify entities. --> + * <mapping class="com.example.Entity"/> + * <mapping class="com.example.ChildEntity"/> + * + * <!-- Enable L2 cache with nonstrict-read-write access strategy for entities and collection. --> + * <collection-cache collection="com.example.Entity" usage="nonstrict-read-write"/> + * <collection-cache collection="com.example.ChildEntity" usage="nonstrict-read-write"/> + * <collection-cache collection="com.example.Entity.children" usage="nonstrict-read-write"/> + * </hibernate-configuration> + * </pre> + * Also cache for collection can be enabled using annotations: + * <pre name="code" class="java"> + * @javax.persistence.Entity + * public class Entity { + * ... + * + * @javax.persistence.OneToMany(cascade=CascadeType.ALL, fetch=FetchType.EAGER) + * @javax.persistence.JoinColumn(name="PARENT_ID") + * @org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE) + * public List<ChildEntity> 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
