Removed support of old libs

pull/2459/head
Nikita Koksharov 5 years ago
parent c9436d0b53
commit 271e842dfe

@ -14,9 +14,6 @@
<name>Redisson/Hibernate</name>
<modules>
<module>redisson-hibernate-4</module>
<module>redisson-hibernate-5</module>
<module>redisson-hibernate-52</module>
<module>redisson-hibernate-53</module>
</modules>

@ -1,84 +0,0 @@
<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.redisson</groupId>
<artifactId>redisson-hibernate</artifactId>
<version>3.11.7-SNAPSHOT</version>
<relativePath>../</relativePath>
</parent>
<artifactId>redisson-hibernate-4</artifactId>
<packaging>jar</packaging>
<name>Redisson/Hibernate-4.x</name>
<dependencies>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>4.3.11.Final</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-testing</artifactId>
<version>4.3.11.Final</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<version>3.1.2</version>
<configuration>
<archive>
<manifestEntries>
<Build-Time>${maven.build.timestamp}</Build-Time>
<Automatic-Module-Name>redisson.hibernate4</Automatic-Module-Name>
</manifestEntries>
</archive>
</configuration>
</plugin>
<plugin>
<groupId>com.mycila</groupId>
<artifactId>license-maven-plugin</artifactId>
<version>3.0</version>
<configuration>
<basedir>${basedir}</basedir>
<header>${basedir}/../../header.txt</header>
<quiet>false</quiet>
<failIfMissing>true</failIfMissing>
<aggregate>false</aggregate>
<includes>
<include>src/main/java/org/redisson/</include>
</includes>
<excludes>
<exclude>target/**</exclude>
</excludes>
<useDefaultExcludes>true</useDefaultExcludes>
<mapping>
<java>JAVADOC_STYLE</java>
</mapping>
<strictCheck>true</strictCheck>
<useDefaultMapping>true</useDefaultMapping>
<encoding>UTF-8</encoding>
</configuration>
<executions>
<execution>
<goals>
<goal>check</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

@ -1,70 +0,0 @@
/**
* Copyright (c) 2013-2019 Nikita Koksharov
*
* 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.
*/
package org.redisson.hibernate;
import java.util.Properties;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import org.hibernate.cache.CacheException;
import org.hibernate.engine.jndi.internal.JndiServiceImpl;
import org.hibernate.internal.util.config.ConfigurationHelper;
import org.redisson.api.RedissonClient;
/**
* Hibernate Cache region factory based on Redisson.
* Uses Redisson instance located in JNDI.
*
* @author Nikita Koksharov
*
*/
public class JndiRedissonRegionFactory extends RedissonRegionFactory {
private static final long serialVersionUID = -4814502675083325567L;
public static final String JNDI_NAME = CONFIG_PREFIX + "jndi_name";
@Override
protected RedissonClient createRedissonClient(Properties properties) {
String jndiName = ConfigurationHelper.getString(JNDI_NAME, properties);
if (jndiName == null) {
throw new CacheException(JNDI_NAME + " property not set");
}
Properties jndiProperties = JndiServiceImpl.extractJndiProperties(properties);
InitialContext context = null;
try {
context = new InitialContext(jndiProperties);
return (RedissonClient) context.lookup(jndiName);
} catch (NamingException e) {
throw new CacheException("Unable to locate Redisson instance by name: " + jndiName, e);
} finally {
if (context != null) {
try {
context.close();
} catch (NamingException e) {
throw new CacheException("Unable to close JNDI context", e);
}
}
}
}
@Override
public void stop() {
}
}

@ -1,219 +0,0 @@
/**
* Copyright (c) 2013-2019 Nikita Koksharov
*
* 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.
*/
package org.redisson.hibernate;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;
import java.util.Properties;
import org.hibernate.cache.CacheException;
import org.hibernate.cache.spi.CacheDataDescription;
import org.hibernate.cache.spi.CollectionRegion;
import org.hibernate.cache.spi.EntityRegion;
import org.hibernate.cache.spi.NaturalIdRegion;
import org.hibernate.cache.spi.QueryResultsRegion;
import org.hibernate.cache.spi.RegionFactory;
import org.hibernate.cache.spi.TimestampsRegion;
import org.hibernate.cache.spi.access.AccessType;
import org.hibernate.cfg.Settings;
import org.hibernate.internal.util.config.ConfigurationHelper;
import org.jboss.logging.Logger;
import org.redisson.Redisson;
import org.redisson.api.RMapCache;
import org.redisson.api.RScript;
import org.redisson.api.RedissonClient;
import org.redisson.client.codec.LongCodec;
import org.redisson.config.Config;
import org.redisson.hibernate.region.RedissonCollectionRegion;
import org.redisson.hibernate.region.RedissonEntityRegion;
import org.redisson.hibernate.region.RedissonNaturalIdRegion;
import org.redisson.hibernate.region.RedissonQueryRegion;
import org.redisson.hibernate.region.RedissonTimestampsRegion;
/**
* Hibernate Cache region factory based on Redisson.
* Creates own Redisson instance during region start.
*
* @author Nikita Koksharov
*
*/
public class RedissonRegionFactory implements RegionFactory {
private static final Logger log = Logger.getLogger( RedissonRegionFactory.class );
private static final long serialVersionUID = 3785315696581773811L;
public static final String QUERY_DEF = "query";
public static final String COLLECTION_DEF = "collection";
public static final String ENTITY_DEF = "entity";
public static final String NATURAL_ID_DEF = "naturalid";
public static final String TIMESTAMPS_DEF = "timestamps";
public static final String MAX_ENTRIES_SUFFIX = ".eviction.max_entries";
public static final String TTL_SUFFIX = ".expiration.time_to_live";
public static final String MAX_IDLE_SUFFIX = ".expiration.max_idle_time";
public static final String CONFIG_PREFIX = "hibernate.cache.redisson.";
public static final String REDISSON_CONFIG_PATH = CONFIG_PREFIX + "config";
protected RedissonClient redisson;
private Settings settings;
@Override
public void start(Settings settings, Properties properties) throws CacheException {
this.redisson = createRedissonClient(properties);
this.settings = settings;
}
protected RedissonClient createRedissonClient(Properties properties) {
Config config = null;
if (!properties.containsKey(REDISSON_CONFIG_PATH)) {
config = loadConfig(RedissonRegionFactory.class.getClassLoader(), "redisson.json");
if (config == null) {
config = loadConfig(RedissonRegionFactory.class.getClassLoader(), "redisson.yaml");
}
} else {
String configPath = ConfigurationHelper.getString(REDISSON_CONFIG_PATH, properties);
config = loadConfig(RedissonRegionFactory.class.getClassLoader(), configPath);
if (config == null) {
config = loadConfig(configPath);
}
}
if (config == null) {
throw new CacheException("Unable to locate Redisson configuration");
}
return Redisson.create(config);
}
private Config loadConfig(String configPath) {
try {
return Config.fromJSON(new File(configPath));
} catch (IOException e) {
// trying next format
try {
return Config.fromYAML(new File(configPath));
} catch (IOException e1) {
throw new CacheException("Can't parse default yaml config", e1);
}
}
}
private Config loadConfig(ClassLoader classLoader, String fileName) {
InputStream is = classLoader.getResourceAsStream(fileName);
if (is != null) {
try {
return Config.fromJSON(is);
} catch (IOException e) {
try {
is = classLoader.getResourceAsStream(fileName);
return Config.fromYAML(is);
} catch (IOException e1) {
throw new CacheException("Can't parse yaml config", e1);
}
}
}
return null;
}
@Override
public void stop() {
redisson.shutdown();
}
@Override
public boolean isMinimalPutsEnabledByDefault() {
return true;
}
@Override
public AccessType getDefaultAccessType() {
return AccessType.TRANSACTIONAL;
}
@Override
public long nextTimestamp() {
long time = System.currentTimeMillis() << 12;
return redisson.getScript(LongCodec.INSTANCE).eval(RScript.Mode.READ_WRITE,
"local currentTime = redis.call('get', KEYS[1]);"
+ "if currentTime == false then "
+ "redis.call('set', KEYS[1], ARGV[1]); "
+ "return ARGV[1]; "
+ "end;"
+ "local nextValue = math.max(tonumber(ARGV[1]), tonumber(currentTime) + 1); "
+ "redis.call('set', KEYS[1], nextValue); "
+ "return nextValue;",
RScript.ReturnType.INTEGER, Arrays.<Object>asList("redisson-hibernate-timestamp"), time);
}
@Override
public EntityRegion buildEntityRegion(String regionName, Properties properties, CacheDataDescription metadata)
throws CacheException {
log.debug("Building entity cache region: " + regionName);
RMapCache<Object, Object> mapCache = getCache(regionName, properties, ENTITY_DEF);
return new RedissonEntityRegion(mapCache, this, metadata, settings, properties, ENTITY_DEF);
}
@Override
public NaturalIdRegion buildNaturalIdRegion(String regionName, Properties properties, CacheDataDescription metadata)
throws CacheException {
log.debug("Building naturalId cache region: " + regionName);
RMapCache<Object, Object> mapCache = getCache(regionName, properties, NATURAL_ID_DEF);
return new RedissonNaturalIdRegion(mapCache, this, metadata, settings, properties, NATURAL_ID_DEF);
}
@Override
public CollectionRegion buildCollectionRegion(String regionName, Properties properties,
CacheDataDescription metadata) throws CacheException {
log.debug("Building collection cache region: " + regionName);
RMapCache<Object, Object> mapCache = getCache(regionName, properties, COLLECTION_DEF);
return new RedissonCollectionRegion(mapCache, this, metadata, settings, properties, COLLECTION_DEF);
}
@Override
public QueryResultsRegion buildQueryResultsRegion(String regionName, Properties properties) throws CacheException {
log.debug("Building query cache region: " + regionName);
RMapCache<Object, Object> mapCache = getCache(regionName, properties, QUERY_DEF);
return new RedissonQueryRegion(mapCache, this, properties, QUERY_DEF);
}
@Override
public TimestampsRegion buildTimestampsRegion(String regionName, Properties properties) throws CacheException {
log.debug("Building timestamps cache region: " + regionName);
RMapCache<Object, Object> mapCache = getCache(regionName, properties, TIMESTAMPS_DEF);
return new RedissonTimestampsRegion(mapCache, this, properties, TIMESTAMPS_DEF);
}
protected RMapCache<Object, Object> getCache(String regionName, Properties properties, String defaultKey) {
return redisson.getMapCache(regionName);
}
}

@ -1,42 +0,0 @@
/**
* Copyright (c) 2013-2019 Nikita Koksharov
*
* 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.
*/
package org.redisson.hibernate;
import java.util.Collections;
import org.hibernate.boot.registry.selector.SimpleStrategyRegistrationImpl;
import org.hibernate.boot.registry.selector.StrategyRegistration;
import org.hibernate.boot.registry.selector.StrategyRegistrationProvider;
import org.hibernate.cache.spi.RegionFactory;
/**
*
* @author Nikita Koksharov
*
*/
public class RedissonStrategyRegistrationProvider implements StrategyRegistrationProvider {
@Override
public Iterable<StrategyRegistration> getStrategyRegistrations() {
return Collections.<StrategyRegistration>singleton(new SimpleStrategyRegistrationImpl(
RegionFactory.class,
RedissonRegionFactory.class,
"redisson",
RedissonRegionFactory.class.getName(),
RedissonRegionFactory.class.getSimpleName()));
}
}

@ -1,178 +0,0 @@
/**
* Copyright (c) 2013-2019 Nikita Koksharov
*
* 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.
*/
package org.redisson.hibernate.region;
import java.util.Collections;
import java.util.Map;
import java.util.Properties;
import java.util.concurrent.TimeUnit;
import org.hibernate.cache.CacheException;
import org.hibernate.cache.spi.CacheDataDescription;
import org.hibernate.cache.spi.GeneralDataRegion;
import org.hibernate.cache.spi.RegionFactory;
import org.hibernate.cache.spi.TransactionalDataRegion;
import org.redisson.api.RMapCache;
import org.redisson.hibernate.RedissonRegionFactory;
/**
*
* @author Nikita Koksharov
*
*/
public class BaseRegion implements TransactionalDataRegion, GeneralDataRegion {
final RMapCache<Object, Object> mapCache;
final RegionFactory regionFactory;
final CacheDataDescription metadata;
int ttl;
int maxIdle;
public BaseRegion(RMapCache<Object, Object> mapCache, RegionFactory regionFactory, CacheDataDescription metadata, Properties properties, String defaultKey) {
super();
this.mapCache = mapCache;
this.regionFactory = regionFactory;
this.metadata = metadata;
String maxEntries = getProperty(properties, mapCache.getName(), defaultKey, RedissonRegionFactory.MAX_ENTRIES_SUFFIX);
if (maxEntries != null) {
mapCache.setMaxSize(Integer.valueOf(maxEntries));
}
String timeToLive = getProperty(properties, mapCache.getName(), defaultKey, RedissonRegionFactory.TTL_SUFFIX);
if (timeToLive != null) {
ttl = Integer.valueOf(timeToLive);
}
String maxIdleTime = getProperty(properties, mapCache.getName(), defaultKey, RedissonRegionFactory.MAX_IDLE_SUFFIX);
if (maxIdleTime != null) {
maxIdle = Integer.valueOf(maxIdleTime);
}
}
private String getProperty(Properties properties, String name, String defaultKey, String suffix) {
String value = properties.getProperty(RedissonRegionFactory.CONFIG_PREFIX + name + suffix);
if (value != null) {
return value;
}
String defValue = properties.getProperty(RedissonRegionFactory.CONFIG_PREFIX + defaultKey + suffix);
if (defValue != null) {
return defValue;
}
return null;
}
@Override
public boolean isTransactionAware() {
// TODO Auto-generated method stub
return false;
}
@Override
public CacheDataDescription getCacheDataDescription() {
return metadata;
}
@Override
public String getName() {
return mapCache.getName();
}
@Override
public void destroy() throws CacheException {
try {
mapCache.destroy();
} catch (Exception e) {
throw new CacheException(e);
}
}
@Override
public boolean contains(Object key) {
try {
return mapCache.containsKey(key);
} catch (Exception e) {
throw new CacheException(e);
}
}
@Override
public long getSizeInMemory() {
return mapCache.sizeInMemory();
}
@Override
public long getElementCountInMemory() {
return mapCache.size();
}
@Override
public long getElementCountOnDisk() {
return -1;
}
@Override
public Map<?, ?> toMap() {
return Collections.unmodifiableMap(mapCache);
}
@Override
public long nextTimestamp() {
return regionFactory.nextTimestamp();
}
@Override
public int getTimeout() {
// 60 seconds (normalized value)
return (1 << 12) * 60000;
}
@Override
public Object get(Object key) throws CacheException {
try {
return mapCache.get(key);
} catch (Exception e) {
throw new CacheException(e);
}
}
@Override
public void put(Object key, Object value) throws CacheException {
try {
mapCache.fastPut(key, value, ttl, TimeUnit.MILLISECONDS, maxIdle, TimeUnit.MILLISECONDS);
} catch (Exception e) {
throw new CacheException(e);
}
}
@Override
public void evict(Object key) throws CacheException {
try {
mapCache.fastRemove(key);
} catch (Exception e) {
throw new CacheException(e);
}
}
@Override
public void evictAll() throws CacheException {
try {
mapCache.clear();
} catch (Exception e) {
throw new CacheException(e);
}
}
}

@ -1,66 +0,0 @@
/**
* Copyright (c) 2013-2019 Nikita Koksharov
*
* 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.
*/
package org.redisson.hibernate.region;
import java.util.Properties;
import org.hibernate.cache.CacheException;
import org.hibernate.cache.spi.CacheDataDescription;
import org.hibernate.cache.spi.CollectionRegion;
import org.hibernate.cache.spi.RegionFactory;
import org.hibernate.cache.spi.access.AccessType;
import org.hibernate.cache.spi.access.CollectionRegionAccessStrategy;
import org.hibernate.cfg.Settings;
import org.redisson.api.RMapCache;
import org.redisson.hibernate.strategy.NonStrictReadWriteCollectionRegionAccessStrategy;
import org.redisson.hibernate.strategy.ReadOnlyCollectionRegionAccessStrategy;
import org.redisson.hibernate.strategy.ReadWriteCollectionRegionAccessStrategy;
import org.redisson.hibernate.strategy.TransactionalCollectionRegionAccessStrategy;
/**
*
* @author Nikita Koksharov
*
*/
public class RedissonCollectionRegion extends BaseRegion implements CollectionRegion {
private final Settings settings;
public RedissonCollectionRegion(RMapCache<Object, Object> mapCache, RegionFactory regionFactory,
CacheDataDescription metadata, Settings settings, Properties properties, String defaultKey) {
super(mapCache, regionFactory, metadata, properties, defaultKey);
this.settings = settings;
}
@Override
public CollectionRegionAccessStrategy buildAccessStrategy(AccessType accessType) throws CacheException {
if (accessType == AccessType.READ_ONLY) {
return new ReadOnlyCollectionRegionAccessStrategy(settings, this);
}
if (accessType == AccessType.READ_WRITE) {
return new ReadWriteCollectionRegionAccessStrategy(settings, this, mapCache);
}
if (accessType == AccessType.NONSTRICT_READ_WRITE) {
return new NonStrictReadWriteCollectionRegionAccessStrategy(settings, this);
}
if (accessType == AccessType.TRANSACTIONAL) {
return new TransactionalCollectionRegionAccessStrategy(settings, this);
}
throw new CacheException("Unsupported access strategy: " + accessType);
}
}

@ -1,66 +0,0 @@
/**
* Copyright (c) 2013-2019 Nikita Koksharov
*
* 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.
*/
package org.redisson.hibernate.region;
import java.util.Properties;
import org.hibernate.cache.CacheException;
import org.hibernate.cache.spi.CacheDataDescription;
import org.hibernate.cache.spi.EntityRegion;
import org.hibernate.cache.spi.RegionFactory;
import org.hibernate.cache.spi.access.AccessType;
import org.hibernate.cache.spi.access.EntityRegionAccessStrategy;
import org.hibernate.cfg.Settings;
import org.redisson.api.RMapCache;
import org.redisson.hibernate.strategy.NonStrictReadWriteEntityRegionAccessStrategy;
import org.redisson.hibernate.strategy.ReadOnlyEntityRegionAccessStrategy;
import org.redisson.hibernate.strategy.ReadWriteEntityRegionAccessStrategy;
import org.redisson.hibernate.strategy.TransactionalEntityRegionAccessStrategy;
/**
*
* @author Nikita Koksharov
*
*/
public class RedissonEntityRegion extends BaseRegion implements EntityRegion {
private final Settings settings;
public RedissonEntityRegion(RMapCache<Object, Object> mapCache, RegionFactory regionFactory,
CacheDataDescription metadata, Settings settings, Properties properties, String defaultKey) {
super(mapCache, regionFactory, metadata, properties, defaultKey);
this.settings = settings;
}
@Override
public EntityRegionAccessStrategy buildAccessStrategy(AccessType accessType) throws CacheException {
if (accessType == AccessType.READ_ONLY) {
return new ReadOnlyEntityRegionAccessStrategy(settings, this);
}
if (accessType == AccessType.READ_WRITE) {
return new ReadWriteEntityRegionAccessStrategy(settings, this, mapCache);
}
if (accessType == AccessType.NONSTRICT_READ_WRITE) {
return new NonStrictReadWriteEntityRegionAccessStrategy(settings, this);
}
if (accessType == AccessType.TRANSACTIONAL) {
return new TransactionalEntityRegionAccessStrategy(settings, this);
}
throw new CacheException("Unsupported access strategy: " + accessType);
}
}

@ -1,66 +0,0 @@
/**
* Copyright (c) 2013-2019 Nikita Koksharov
*
* 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.
*/
package org.redisson.hibernate.region;
import java.util.Properties;
import org.hibernate.cache.CacheException;
import org.hibernate.cache.spi.CacheDataDescription;
import org.hibernate.cache.spi.NaturalIdRegion;
import org.hibernate.cache.spi.RegionFactory;
import org.hibernate.cache.spi.access.AccessType;
import org.hibernate.cache.spi.access.NaturalIdRegionAccessStrategy;
import org.hibernate.cfg.Settings;
import org.redisson.api.RMapCache;
import org.redisson.hibernate.strategy.NonStrictReadWriteNaturalIdRegionAccessStrategy;
import org.redisson.hibernate.strategy.ReadOnlyNaturalIdRegionAccessStrategy;
import org.redisson.hibernate.strategy.ReadWriteNaturalIdRegionAccessStrategy;
import org.redisson.hibernate.strategy.TransactionalNaturalIdRegionAccessStrategy;
/**
*
* @author Nikita Koksharov
*
*/
public class RedissonNaturalIdRegion extends BaseRegion implements NaturalIdRegion {
private final Settings settings;
public RedissonNaturalIdRegion(RMapCache<Object, Object> mapCache, RegionFactory regionFactory,
CacheDataDescription metadata, Settings settings, Properties properties, String defaultKey) {
super(mapCache, regionFactory, metadata, properties, defaultKey);
this.settings = settings;
}
@Override
public NaturalIdRegionAccessStrategy buildAccessStrategy(AccessType accessType) throws CacheException {
if (accessType == AccessType.READ_ONLY) {
return new ReadOnlyNaturalIdRegionAccessStrategy(settings, this);
}
if (accessType == AccessType.READ_WRITE) {
return new ReadWriteNaturalIdRegionAccessStrategy(settings, this, mapCache);
}
if (accessType == AccessType.NONSTRICT_READ_WRITE) {
return new NonStrictReadWriteNaturalIdRegionAccessStrategy(settings, this);
}
if (accessType == AccessType.TRANSACTIONAL) {
return new TransactionalNaturalIdRegionAccessStrategy(settings, this);
}
throw new CacheException("Unsupported access strategy: " + accessType);
}
}

@ -1,36 +0,0 @@
/**
* Copyright (c) 2013-2019 Nikita Koksharov
*
* 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.
*/
package org.redisson.hibernate.region;
import java.util.Properties;
import org.hibernate.cache.spi.QueryResultsRegion;
import org.hibernate.cache.spi.RegionFactory;
import org.redisson.api.RMapCache;
/**
*
* @author Nikita Koksharov
*
*/
public class RedissonQueryRegion extends BaseRegion implements QueryResultsRegion {
public RedissonQueryRegion(RMapCache<Object, Object> mapCache,
RegionFactory regionFactory, Properties properties, String defaultKey) {
super(mapCache, regionFactory, null, properties, defaultKey);
}
}

@ -1,36 +0,0 @@
/**
* Copyright (c) 2013-2019 Nikita Koksharov
*
* 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.
*/
package org.redisson.hibernate.region;
import java.util.Properties;
import org.hibernate.cache.spi.RegionFactory;
import org.hibernate.cache.spi.TimestampsRegion;
import org.redisson.api.RMapCache;
/**
*
* @author Nikita Koksharov
*
*/
public class RedissonTimestampsRegion extends BaseRegion implements TimestampsRegion {
public RedissonTimestampsRegion(RMapCache<Object, Object> mapCache,
RegionFactory regionFactory, Properties properties, String defaultKey) {
super(mapCache, regionFactory, null, properties, defaultKey);
}
}

@ -1,355 +0,0 @@
/**
* Copyright (c) 2013-2019 Nikita Koksharov
*
* 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.
*/
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2010-2011, Red Hat Inc. or third-party contributors as
* indicated by the @author tags or express copyright attribution
* statements applied by the authors. All third-party contributions are
* distributed under license by Red Hat Inc.
*
* This copyrighted material is made available to anyone wishing to use, modify,
* copy, or redistribute it subject to the terms and conditions of the GNU
* Lesser General Public License, as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this distribution; if not, write to:
* Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
package org.redisson.hibernate.strategy;
import java.io.Serializable;
import java.util.Comparator;
import java.util.UUID;
import java.util.concurrent.atomic.AtomicLong;
import org.hibernate.cache.CacheException;
import org.hibernate.cache.spi.GeneralDataRegion;
import org.hibernate.cache.spi.TransactionalDataRegion;
import org.hibernate.cache.spi.access.SoftLock;
import org.hibernate.cfg.Settings;
import org.redisson.api.RLock;
import org.redisson.api.RMapCache;
/**
*
* @author Nikita Koksharov
* @author Strong Liu
*
*/
public class AbstractReadWriteAccessStrategy extends BaseRegionAccessStrategy {
private final UUID uuid = UUID.randomUUID();
private final AtomicLong nextLockId = new AtomicLong();
final RMapCache<Object, Object> mapCache;
public AbstractReadWriteAccessStrategy(Settings settings, GeneralDataRegion region, RMapCache<Object, Object> mapCache) {
super(settings, region);
this.mapCache = mapCache;
}
@Override
public Object get(Object key, long txTimestamp) throws CacheException {
RLock readLock = mapCache.getReadWriteLock(key).readLock();
readLock.lock();
try {
Lockable item = (Lockable) region.get( key );
if (item != null && item.isReadable(txTimestamp)) {
return item.getValue();
} else {
return null;
}
} finally {
readLock.unlock();
}
}
@Override
public boolean putFromLoad(Object key, Object value, long txTimestamp, Object version, boolean minimalPutOverride)
throws CacheException {
RLock writeLock = mapCache.getReadWriteLock(key).writeLock();
writeLock.lock();
try {
Lockable item = (Lockable) region.get(key);
Comparator<Object> comparator = ((TransactionalDataRegion)region).getCacheDataDescription().getVersionComparator();
boolean writeable = item == null || item.isWriteable(txTimestamp, version, comparator);
if (writeable) {
region.put(key, new Item(value, version, region.nextTimestamp()));
return true;
}
return false;
} finally {
writeLock.unlock();
}
}
@Override
public SoftLock lockItem(Object key, Object version) throws CacheException {
RLock writeLock = mapCache.getReadWriteLock(key).writeLock();
writeLock.lock();
try {
Lockable item = (Lockable) region.get( key );
long timeout = region.nextTimestamp() + region.getTimeout();
Lock lock;
if (item == null) {
lock = new Lock(timeout, uuid, nextLockId.getAndIncrement(), version);
} else {
lock = item.lock(timeout, uuid, nextLockId.getAndIncrement());
}
region.put( key, lock );
return lock;
} finally {
writeLock.unlock();
}
}
@Override
public void unlockItem(Object key, SoftLock lock) throws CacheException {
RLock writeLock = mapCache.getReadWriteLock(key).writeLock();
writeLock.lock();
try {
Lockable item = (Lockable) region.get(key);
if (item != null && item.isUnlockable(lock)) {
decrementLock(key, (Lock)item);
} else {
handleLockExpiry(key, item);
}
} finally {
writeLock.unlock();
}
}
/**
* Unlock and re-put the given key, lock combination.
*/
protected void decrementLock(Object key, Lock lock) {
lock.unlock(region.nextTimestamp());
region.put(key, lock);
}
/**
* Handle the timeout of a previous lock mapped to this key
*/
protected void handleLockExpiry(Object key, Lockable lock) {
long ts = region.nextTimestamp() + region.getTimeout();
// create new lock that times out immediately
Lock newLock = new Lock(ts, uuid, nextLockId.getAndIncrement(), null);
newLock.unlock(ts);
region.put(key, newLock);
}
/**
* Interface type implemented by all wrapper objects in the cache.
*/
public interface Lockable {
/**
* Returns <code>true</code> if the enclosed value can be read by a transaction started at the given time.
*/
public boolean isReadable(long txTimestamp);
/**
* Returns <code>true</code> if the enclosed value can be replaced with one of the given version by a
* transaction started at the given time.
*/
public boolean isWriteable(long txTimestamp, Object version, Comparator<Object> versionComparator);
/**
* Returns the enclosed value.
*/
public Object getValue();
/**
* Returns <code>true</code> if the given lock can be unlocked using the given SoftLock instance as a handle.
*/
public boolean isUnlockable(SoftLock lock);
/**
* Locks this entry, stamping it with the UUID and lockId given, with the lock timeout occuring at the specified
* time. The returned Lock object can be used to unlock the entry in the future.
*/
public Lock lock(long timeout, UUID uuid, long lockId);
}
/**
* Wrapper type representing unlocked items.
*/
public final static class Item implements Serializable, Lockable {
private static final long serialVersionUID = 1L;
private Object value;
private Object version;
private long timestamp;
/**
* Creates an unlocked item wrapping the given value with a version and creation timestamp.
*/
public Item(Object value, Object version, long timestamp) {
this.value = value;
this.version = version;
this.timestamp = timestamp;
}
@Override
public boolean isReadable(long txTimestamp) {
return txTimestamp > timestamp;
}
@Override
public boolean isWriteable(long txTimestamp, Object newVersion, Comparator<Object> versionComparator) {
return version != null && versionComparator.compare( version, newVersion ) < 0;
}
@Override
public Object getValue() {
return value;
}
@Override
public boolean isUnlockable(SoftLock lock) {
return false;
}
@Override
public Lock lock(long timeout, UUID uuid, long lockId) {
return new Lock(timeout, uuid, lockId, version);
}
}
/**
* Wrapper type representing locked items.
*/
public final static class Lock implements Serializable, Lockable, SoftLock {
private static final long serialVersionUID = 2L;
private UUID sourceUuid;
private long lockId;
private Object version;
private long timeout;
private boolean concurrent;
private int multiplicity = 1;
private long unlockTimestamp;
/**
* Creates a locked item with the given identifiers and object version.
*/
public Lock(long timeout, UUID sourceUuid, long lockId, Object version) {
this.timeout = timeout;
this.lockId = lockId;
this.version = version;
this.sourceUuid = sourceUuid;
}
@Override
public boolean isReadable(long txTimestamp) {
return false;
}
@Override
public boolean isWriteable(long txTimestamp, Object newVersion, Comparator versionComparator) {
if ( txTimestamp > timeout ) {
// if timedout then allow write
return true;
}
if ( multiplicity > 0 ) {
// if still locked then disallow write
return false;
}
return version == null ? txTimestamp > unlockTimestamp : versionComparator.compare(
version,
newVersion
) < 0;
}
@Override
public Object getValue() {
return null;
}
@Override
public boolean isUnlockable(SoftLock lock) {
return equals( lock );
}
@Override
public boolean equals(Object o) {
if ( o == this ) {
return true;
}
else if ( o instanceof Lock ) {
return ( lockId == ( (Lock) o ).lockId ) && sourceUuid.equals( ( (Lock) o ).sourceUuid );
}
else {
return false;
}
}
@Override
public int hashCode() {
int hash = ( sourceUuid != null ? sourceUuid.hashCode() : 0 );
int temp = (int) lockId;
for ( int i = 1; i < Long.SIZE / Integer.SIZE; i++ ) {
temp ^= ( lockId >>> ( i * Integer.SIZE ) );
}
return hash + temp;
}
/**
* Returns true if this Lock has been concurrently locked by more than one transaction.
*/
public boolean wasLockedConcurrently() {
return concurrent;
}
@Override
public Lock lock(long timeout, UUID uuid, long lockId) {
concurrent = true;
multiplicity++;
this.timeout = timeout;
return this;
}
/**
* Unlocks this Lock, and timestamps the unlock event.
*/
public void unlock(long timestamp) {
if ( --multiplicity == 0 ) {
unlockTimestamp = timestamp;
}
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder( "Lock Source-UUID:" + sourceUuid + " Lock-ID:" + lockId );
return sb.toString();
}
}
}

@ -1,73 +0,0 @@
/**
* Copyright (c) 2013-2019 Nikita Koksharov
*
* 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.
*/
package org.redisson.hibernate.strategy;
import org.hibernate.cache.CacheException;
import org.hibernate.cache.spi.GeneralDataRegion;
import org.hibernate.cache.spi.access.RegionAccessStrategy;
import org.hibernate.cache.spi.access.SoftLock;
import org.hibernate.cfg.Settings;
/**
*
* @author Nikita Koksharov
*
*/
abstract class BaseRegionAccessStrategy implements RegionAccessStrategy {
final GeneralDataRegion region;
final Settings settings;
BaseRegionAccessStrategy(Settings settings, GeneralDataRegion region) {
this.settings = settings;
this.region = region;
}
@Override
public boolean putFromLoad(Object key, Object value, long txTimestamp, Object version) throws CacheException {
return putFromLoad( key, value, txTimestamp, version, settings.isMinimalPutsEnabled() );
}
@Override
public SoftLock lockRegion() throws CacheException {
return null;
}
@Override
public void unlockRegion(SoftLock lock) throws CacheException {
region.evictAll();
}
@Override
public void remove(Object key) throws CacheException {
}
@Override
public void removeAll() throws CacheException {
region.evictAll();
}
@Override
public void evict(Object key) throws CacheException {
region.evict(key);
}
@Override
public void evictAll() throws CacheException {
region.evictAll();
}
}

@ -1,72 +0,0 @@
/**
* Copyright (c) 2013-2019 Nikita Koksharov
*
* 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.
*/
package org.redisson.hibernate.strategy;
import org.hibernate.cache.CacheException;
import org.hibernate.cache.spi.CollectionRegion;
import org.hibernate.cache.spi.GeneralDataRegion;
import org.hibernate.cache.spi.access.CollectionRegionAccessStrategy;
import org.hibernate.cache.spi.access.SoftLock;
import org.hibernate.cfg.Settings;
/**
*
* @author Nikita Koksharov
*
*/
public class NonStrictReadWriteCollectionRegionAccessStrategy extends BaseRegionAccessStrategy implements CollectionRegionAccessStrategy {
public NonStrictReadWriteCollectionRegionAccessStrategy(Settings settings, GeneralDataRegion region) {
super(settings, region);
}
@Override
public CollectionRegion getRegion() {
return (CollectionRegion) region;
}
@Override
public Object get(Object key, long txTimestamp) throws CacheException {
return region.get(key);
}
@Override
public boolean putFromLoad(Object key, Object value, long txTimestamp, Object version, boolean minimalPutOverride)
throws CacheException {
if (minimalPutOverride && region.contains(key)) {
return false;
}
region.put(key, value);
return true;
}
@Override
public SoftLock lockItem(Object key, Object version) throws CacheException {
return null;
}
@Override
public void unlockItem(Object key, SoftLock lock) throws CacheException {
evict(key);
}
@Override
public void remove(Object key) throws CacheException {
evict(key);
}
}

@ -1,96 +0,0 @@
/**
* Copyright (c) 2013-2019 Nikita Koksharov
*
* 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.
*/
package org.redisson.hibernate.strategy;
import org.hibernate.cache.CacheException;
import org.hibernate.cache.spi.EntityRegion;
import org.hibernate.cache.spi.GeneralDataRegion;
import org.hibernate.cache.spi.access.EntityRegionAccessStrategy;
import org.hibernate.cache.spi.access.SoftLock;
import org.hibernate.cfg.Settings;
/**
*
* @author Nikita Koksharov
*
*/
public class NonStrictReadWriteEntityRegionAccessStrategy extends BaseRegionAccessStrategy implements EntityRegionAccessStrategy {
public NonStrictReadWriteEntityRegionAccessStrategy(Settings settings, GeneralDataRegion region) {
super(settings, region);
}
@Override
public Object get(Object key, long txTimestamp) throws CacheException {
return region.get(key);
}
@Override
public boolean putFromLoad(Object key, Object value, long txTimestamp, Object version, boolean minimalPutOverride)
throws CacheException {
if (minimalPutOverride && region.contains(key)) {
return false;
}
region.put(key, value);
return true;
}
@Override
public SoftLock lockItem(Object key, Object version) throws CacheException {
return null;
}
@Override
public void unlockItem(Object key, SoftLock lock) throws CacheException {
evict(key);
}
@Override
public EntityRegion getRegion() {
return (EntityRegion) region;
}
@Override
public boolean insert(Object key, Object value, Object version) throws CacheException {
return false;
}
@Override
public boolean afterInsert(Object key, Object value, Object version) throws CacheException {
return false;
}
@Override
public boolean update(Object key, Object value, Object currentVersion, Object previousVersion)
throws CacheException {
remove(key);
return false;
}
@Override
public boolean afterUpdate(Object key, Object value, Object currentVersion, Object previousVersion, SoftLock lock)
throws CacheException {
unlockItem(key, lock);
return false;
}
@Override
public void remove(Object key) throws CacheException {
evict(key);
}
}

@ -1,94 +0,0 @@
/**
* Copyright (c) 2013-2019 Nikita Koksharov
*
* 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.
*/
package org.redisson.hibernate.strategy;
import org.hibernate.cache.CacheException;
import org.hibernate.cache.spi.GeneralDataRegion;
import org.hibernate.cache.spi.NaturalIdRegion;
import org.hibernate.cache.spi.access.NaturalIdRegionAccessStrategy;
import org.hibernate.cache.spi.access.SoftLock;
import org.hibernate.cfg.Settings;
/**
*
* @author Nikita Koksharov
*
*/
public class NonStrictReadWriteNaturalIdRegionAccessStrategy extends BaseRegionAccessStrategy implements NaturalIdRegionAccessStrategy {
public NonStrictReadWriteNaturalIdRegionAccessStrategy(Settings settings, GeneralDataRegion region) {
super(settings, region);
}
@Override
public Object get(Object key, long txTimestamp) throws CacheException {
return region.get(key);
}
@Override
public boolean putFromLoad(Object key, Object value, long txTimestamp, Object version, boolean minimalPutOverride)
throws CacheException {
if (minimalPutOverride && region.contains(key)) {
return false;
}
region.put(key, value);
return true;
}
@Override
public SoftLock lockItem(Object key, Object version) throws CacheException {
return null;
}
@Override
public void unlockItem(Object key, SoftLock lock) throws CacheException {
evict(key);
}
@Override
public NaturalIdRegion getRegion() {
return (NaturalIdRegion) region;
}
@Override
public boolean insert(Object key, Object value) throws CacheException {
return false;
}
@Override
public boolean afterInsert(Object key, Object value) throws CacheException {
return false;
}
@Override
public boolean update(Object key, Object value) throws CacheException {
remove(key);
return false;
}
@Override
public boolean afterUpdate(Object key, Object value, SoftLock lock) throws CacheException {
unlockItem(key, lock);
return false;
}
@Override
public void remove(Object key) throws CacheException {
region.evict(key);
}
}

@ -1,66 +0,0 @@
/**
* Copyright (c) 2013-2019 Nikita Koksharov
*
* 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.
*/
package org.redisson.hibernate.strategy;
import org.hibernate.cache.CacheException;
import org.hibernate.cache.spi.CollectionRegion;
import org.hibernate.cache.spi.GeneralDataRegion;
import org.hibernate.cache.spi.access.CollectionRegionAccessStrategy;
import org.hibernate.cache.spi.access.SoftLock;
import org.hibernate.cfg.Settings;
/**
*
* @author Nikita Koksharov
*
*/
public class ReadOnlyCollectionRegionAccessStrategy extends BaseRegionAccessStrategy implements CollectionRegionAccessStrategy {
public ReadOnlyCollectionRegionAccessStrategy(Settings settings, GeneralDataRegion region) {
super(settings, region);
}
@Override
public CollectionRegion getRegion() {
return (CollectionRegion) region;
}
@Override
public Object get(Object key, long txTimestamp) throws CacheException {
return region.get(key);
}
@Override
public boolean putFromLoad(Object key, Object value, long txTimestamp, Object version, boolean minimalPutOverride)
throws CacheException {
if (minimalPutOverride && region.contains(key)) {
return false;
}
region.put(key, value);
return true;
}
@Override
public SoftLock lockItem(Object key, Object version) throws CacheException {
return null;
}
@Override
public void unlockItem(Object key, SoftLock lock) throws CacheException {
}
}

@ -1,90 +0,0 @@
/**
* Copyright (c) 2013-2019 Nikita Koksharov
*
* 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.
*/
package org.redisson.hibernate.strategy;
import org.hibernate.cache.CacheException;
import org.hibernate.cache.spi.EntityRegion;
import org.hibernate.cache.spi.GeneralDataRegion;
import org.hibernate.cache.spi.access.EntityRegionAccessStrategy;
import org.hibernate.cache.spi.access.SoftLock;
import org.hibernate.cfg.Settings;
/**
*
* @author Nikita Koksharov
*
*/
public class ReadOnlyEntityRegionAccessStrategy extends BaseRegionAccessStrategy implements EntityRegionAccessStrategy {
public ReadOnlyEntityRegionAccessStrategy(Settings settings, GeneralDataRegion region) {
super(settings, region);
}
@Override
public Object get(Object key, long txTimestamp) throws CacheException {
return region.get(key);
}
@Override
public boolean putFromLoad(Object key, Object value, long txTimestamp, Object version, boolean minimalPutOverride)
throws CacheException {
if (minimalPutOverride && region.contains(key)) {
return false;
}
region.put(key, value);
return true;
}
@Override
public SoftLock lockItem(Object key, Object version) throws CacheException {
return null;
}
@Override
public void unlockItem(Object key, SoftLock lock) throws CacheException {
evict(key);
}
@Override
public EntityRegion getRegion() {
return (EntityRegion) region;
}
@Override
public boolean insert(Object key, Object value, Object version) throws CacheException {
return false;
}
@Override
public boolean afterInsert(Object key, Object value, Object version) throws CacheException {
region.put(key, value);
return true;
}
@Override
public boolean update(Object key, Object value, Object currentVersion, Object previousVersion)
throws CacheException {
throw new UnsupportedOperationException("Unable to update read-only object");
}
@Override
public boolean afterUpdate(Object key, Object value, Object currentVersion, Object previousVersion, SoftLock lock)
throws CacheException {
throw new UnsupportedOperationException("Unable to update read-only object");
}
}

@ -1,88 +0,0 @@
/**
* Copyright (c) 2013-2019 Nikita Koksharov
*
* 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.
*/
package org.redisson.hibernate.strategy;
import org.hibernate.cache.CacheException;
import org.hibernate.cache.spi.GeneralDataRegion;
import org.hibernate.cache.spi.NaturalIdRegion;
import org.hibernate.cache.spi.access.NaturalIdRegionAccessStrategy;
import org.hibernate.cache.spi.access.SoftLock;
import org.hibernate.cfg.Settings;
/**
*
* @author Nikita Koksharov
*
*/
public class ReadOnlyNaturalIdRegionAccessStrategy extends BaseRegionAccessStrategy implements NaturalIdRegionAccessStrategy {
public ReadOnlyNaturalIdRegionAccessStrategy(Settings settings, GeneralDataRegion region) {
super(settings, region);
}
@Override
public Object get(Object key, long txTimestamp) throws CacheException {
return region.get(key);
}
@Override
public boolean putFromLoad(Object key, Object value, long txTimestamp, Object version, boolean minimalPutOverride)
throws CacheException {
if (minimalPutOverride && region.contains(key)) {
return false;
}
region.put(key, value);
return true;
}
@Override
public SoftLock lockItem(Object key, Object version) throws CacheException {
return null;
}
@Override
public void unlockItem(Object key, SoftLock lock) throws CacheException {
evict(key);
}
@Override
public NaturalIdRegion getRegion() {
return (NaturalIdRegion) region;
}
@Override
public boolean insert(Object key, Object value) throws CacheException {
return false;
}
@Override
public boolean afterInsert(Object key, Object value) throws CacheException {
region.put(key, value);
return true;
}
@Override
public boolean update(Object key, Object value) throws CacheException {
throw new UnsupportedOperationException("Unable to update read-only object");
}
@Override
public boolean afterUpdate(Object key, Object value, SoftLock lock) throws CacheException {
throw new UnsupportedOperationException("Unable to update read-only object");
}
}

@ -1,41 +0,0 @@
/**
* Copyright (c) 2013-2019 Nikita Koksharov
*
* 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.
*/
package org.redisson.hibernate.strategy;
import org.hibernate.cache.spi.CollectionRegion;
import org.hibernate.cache.spi.GeneralDataRegion;
import org.hibernate.cache.spi.access.CollectionRegionAccessStrategy;
import org.hibernate.cfg.Settings;
import org.redisson.api.RMapCache;
/**
*
* @author Nikita Koksharov
*
*/
public class ReadWriteCollectionRegionAccessStrategy extends AbstractReadWriteAccessStrategy implements CollectionRegionAccessStrategy {
public ReadWriteCollectionRegionAccessStrategy(Settings settings, GeneralDataRegion region,
RMapCache<Object, Object> mapCache) {
super(settings, region, mapCache);
}
@Override
public CollectionRegion getRegion() {
return (CollectionRegion) region;
}
}

@ -1,121 +0,0 @@
/**
* Copyright (c) 2013-2019 Nikita Koksharov
*
* 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.
*/
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2010-2011, Red Hat Inc. or third-party contributors as
* indicated by the @author tags or express copyright attribution
* statements applied by the authors. All third-party contributions are
* distributed under license by Red Hat Inc.
*
* This copyrighted material is made available to anyone wishing to use, modify,
* copy, or redistribute it subject to the terms and conditions of the GNU
* Lesser General Public License, as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this distribution; if not, write to:
* Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
package org.redisson.hibernate.strategy;
import org.hibernate.cache.CacheException;
import org.hibernate.cache.spi.EntityRegion;
import org.hibernate.cache.spi.GeneralDataRegion;
import org.hibernate.cache.spi.access.EntityRegionAccessStrategy;
import org.hibernate.cache.spi.access.SoftLock;
import org.hibernate.cfg.Settings;
import org.redisson.api.RLock;
import org.redisson.api.RMapCache;
/**
*
* @author Nikita Koksharov
* @author Strong Liu
*
*/
public class ReadWriteEntityRegionAccessStrategy extends AbstractReadWriteAccessStrategy implements EntityRegionAccessStrategy {
public ReadWriteEntityRegionAccessStrategy(Settings settings, GeneralDataRegion region, RMapCache<Object, Object> mapCache) {
super(settings, region, mapCache);
}
@Override
public EntityRegion getRegion() {
return (EntityRegion) region;
}
@Override
public boolean insert(Object key, Object value, Object version) throws CacheException {
return false;
}
@Override
public boolean afterInsert(Object key, Object value, Object version) throws CacheException {
RLock writeLock = mapCache.getReadWriteLock(key).writeLock();
writeLock.lock();
try {
Lockable item = (Lockable) region.get(key);
if (item == null) {
region.put(key, new Item(value, version, region.nextTimestamp()));
return true;
} else {
return false;
}
} finally {
writeLock.unlock();
}
}
@Override
public boolean update(Object key, Object value, Object currentVersion, Object previousVersion)
throws CacheException {
return false;
}
@Override
public boolean afterUpdate(Object key, Object value, Object currentVersion, Object previousVersion, SoftLock lock)
throws CacheException {
RLock writeLock = mapCache.getReadWriteLock(key).writeLock();
writeLock.lock();
try {
Lockable item = (Lockable) region.get(key);
if (item != null && item.isUnlockable(lock)) {
Lock lockItem = (Lock) item;
if (lockItem.wasLockedConcurrently()) {
decrementLock( key, lockItem );
return false;
} else {
region.put( key, new Item(value, currentVersion, region.nextTimestamp()));
return true;
}
} else {
handleLockExpiry( key, item );
return false;
}
} finally {
writeLock.unlock();
}
}
}

@ -1,120 +0,0 @@
/**
* Copyright (c) 2013-2019 Nikita Koksharov
*
* 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.
*/
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2010-2011, Red Hat Inc. or third-party contributors as
* indicated by the @author tags or express copyright attribution
* statements applied by the authors. All third-party contributions are
* distributed under license by Red Hat Inc.
*
* This copyrighted material is made available to anyone wishing to use, modify,
* copy, or redistribute it subject to the terms and conditions of the GNU
* Lesser General Public License, as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this distribution; if not, write to:
* Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
package org.redisson.hibernate.strategy;
import org.hibernate.cache.CacheException;
import org.hibernate.cache.spi.GeneralDataRegion;
import org.hibernate.cache.spi.NaturalIdRegion;
import org.hibernate.cache.spi.access.NaturalIdRegionAccessStrategy;
import org.hibernate.cache.spi.access.SoftLock;
import org.hibernate.cfg.Settings;
import org.redisson.api.RLock;
import org.redisson.api.RMapCache;
/**
*
* @author Nikita Koksharov
* @author Eric Dalquist
*
*/
public class ReadWriteNaturalIdRegionAccessStrategy extends AbstractReadWriteAccessStrategy implements NaturalIdRegionAccessStrategy {
public ReadWriteNaturalIdRegionAccessStrategy(Settings settings, GeneralDataRegion region,
RMapCache<Object, Object> mapCache) {
super(settings, region, mapCache);
}
@Override
public NaturalIdRegion getRegion() {
return (NaturalIdRegion) region;
}
@Override
public boolean insert(Object key, Object value) throws CacheException {
return false;
}
@Override
public boolean afterInsert(Object key, Object value) throws CacheException {
RLock writeLock = mapCache.getReadWriteLock(key).writeLock();
writeLock.lock();
try {
Lockable item = (Lockable) region.get(key);
if (item == null) {
region.put(key, new Item(value, null, region.nextTimestamp()));
return true;
} else {
return false;
}
} finally {
writeLock.unlock();
}
}
@Override
public boolean update(Object key, Object value) throws CacheException {
return false;
}
@Override
public boolean afterUpdate(Object key, Object value, SoftLock lock) throws CacheException {
RLock writeLock = mapCache.getReadWriteLock(key).writeLock();
writeLock.lock();
try {
Lockable item = (Lockable) region.get(key);
if (item != null && item.isUnlockable(lock)) {
Lock lockItem = (Lock) item;
if (lockItem.wasLockedConcurrently()) {
decrementLock(key, lockItem);
return false;
} else {
region.put(key, new Item(value, null, region.nextTimestamp()));
return true;
}
} else {
handleLockExpiry(key, item);
return false;
}
} finally {
writeLock.unlock();
}
}
}

@ -1,71 +0,0 @@
/**
* Copyright (c) 2013-2019 Nikita Koksharov
*
* 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.
*/
package org.redisson.hibernate.strategy;
import org.hibernate.cache.CacheException;
import org.hibernate.cache.spi.CollectionRegion;
import org.hibernate.cache.spi.GeneralDataRegion;
import org.hibernate.cache.spi.access.CollectionRegionAccessStrategy;
import org.hibernate.cache.spi.access.SoftLock;
import org.hibernate.cfg.Settings;
/**
*
* @author Nikita Koksharov
*
*/
public class TransactionalCollectionRegionAccessStrategy extends BaseRegionAccessStrategy implements CollectionRegionAccessStrategy {
public TransactionalCollectionRegionAccessStrategy(Settings settings, GeneralDataRegion region) {
super(settings, region);
}
@Override
public CollectionRegion getRegion() {
return (CollectionRegion) region;
}
@Override
public Object get(Object key, long txTimestamp) throws CacheException {
return region.get(key);
}
@Override
public boolean putFromLoad(Object key, Object value, long txTimestamp, Object version, boolean minimalPutOverride)
throws CacheException {
if (minimalPutOverride && region.contains(key)) {
return false;
}
region.put(key, value);
return true;
}
@Override
public SoftLock lockItem(Object key, Object version) throws CacheException {
return null;
}
@Override
public void unlockItem(Object key, SoftLock lock) throws CacheException {
}
@Override
public void remove(Object key) throws CacheException {
region.evict(key);
}
}

@ -1,94 +0,0 @@
/**
* Copyright (c) 2013-2019 Nikita Koksharov
*
* 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.
*/
package org.redisson.hibernate.strategy;
import org.hibernate.cache.CacheException;
import org.hibernate.cache.spi.EntityRegion;
import org.hibernate.cache.spi.GeneralDataRegion;
import org.hibernate.cache.spi.access.EntityRegionAccessStrategy;
import org.hibernate.cache.spi.access.SoftLock;
import org.hibernate.cfg.Settings;
/**
*
* @author Nikita Koksharov
*
*/
public class TransactionalEntityRegionAccessStrategy extends BaseRegionAccessStrategy implements EntityRegionAccessStrategy {
public TransactionalEntityRegionAccessStrategy(Settings settings, GeneralDataRegion region) {
super(settings, region);
}
@Override
public Object get(Object key, long txTimestamp) throws CacheException {
return region.get(key);
}
@Override
public boolean putFromLoad(Object key, Object value, long txTimestamp, Object version, boolean minimalPutOverride)
throws CacheException {
if (minimalPutOverride && region.contains(key)) {
return false;
}
region.put(key, value);
return true;
}
@Override
public SoftLock lockItem(Object key, Object version) throws CacheException {
return null;
}
@Override
public void unlockItem(Object key, SoftLock lock) throws CacheException {
}
@Override
public EntityRegion getRegion() {
return (EntityRegion) region;
}
@Override
public boolean insert(Object key, Object value, Object version) throws CacheException {
region.put(key, value);
return true;
}
@Override
public boolean afterInsert(Object key, Object value, Object version) throws CacheException {
return false;
}
@Override
public void remove(Object key) throws CacheException {
region.evict(key);
}
@Override
public boolean update(Object key, Object value, Object currentVersion, Object previousVersion)
throws CacheException {
return insert(key, value, currentVersion);
}
@Override
public boolean afterUpdate(Object key, Object value, Object currentVersion, Object previousVersion, SoftLock lock)
throws CacheException {
return false;
}
}

@ -1,92 +0,0 @@
/**
* Copyright (c) 2013-2019 Nikita Koksharov
*
* 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.
*/
package org.redisson.hibernate.strategy;
import org.hibernate.cache.CacheException;
import org.hibernate.cache.spi.GeneralDataRegion;
import org.hibernate.cache.spi.NaturalIdRegion;
import org.hibernate.cache.spi.access.NaturalIdRegionAccessStrategy;
import org.hibernate.cache.spi.access.SoftLock;
import org.hibernate.cfg.Settings;
/**
*
* @author Nikita Koksharov
*
*/
public class TransactionalNaturalIdRegionAccessStrategy extends BaseRegionAccessStrategy implements NaturalIdRegionAccessStrategy {
public TransactionalNaturalIdRegionAccessStrategy(Settings settings, GeneralDataRegion region) {
super(settings, region);
}
@Override
public Object get(Object key, long txTimestamp) throws CacheException {
return region.get(key);
}
@Override
public boolean putFromLoad(Object key, Object value, long txTimestamp, Object version, boolean minimalPutOverride)
throws CacheException {
if (minimalPutOverride && region.contains(key)) {
return false;
}
region.put(key, value);
return true;
}
@Override
public SoftLock lockItem(Object key, Object version) throws CacheException {
return null;
}
@Override
public void unlockItem(Object key, SoftLock lock) throws CacheException {
}
@Override
public NaturalIdRegion getRegion() {
return (NaturalIdRegion) region;
}
@Override
public void remove(Object key) throws CacheException {
region.evict(key);
}
@Override
public boolean insert(Object key, Object value) throws CacheException {
region.put(key, value);
return true;
}
@Override
public boolean afterInsert(Object key, Object value) throws CacheException {
return false;
}
@Override
public boolean update(Object key, Object value) throws CacheException {
return insert(key, value);
}
@Override
public boolean afterUpdate(Object key, Object value, SoftLock lock) throws CacheException {
return false;
}
}

@ -1,11 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<blueprint default-activation="eager"
xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<bean id="strategyRegistrationProvider" class="org.redisson.hibernate.RedissonStrategyRegistrationProvider"/>
<service ref="strategyRegistrationProvider" interface="org.hibernate.boot.registry.selector.StrategyRegistrationProvider"/>
</blueprint>

@ -1,84 +0,0 @@
package org.redisson.hibernate;
import java.util.ArrayList;
import java.util.List;
import javax.persistence.Column;
import javax.persistence.ElementCollection;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import org.hibernate.annotations.Cache;
import org.hibernate.annotations.CacheConcurrencyStrategy;
import org.hibernate.annotations.GenericGenerator;
import org.hibernate.annotations.NaturalId;
import org.hibernate.annotations.NaturalIdCache;
/**
*
* @author Nikita Koksharov
*
*/
@Entity
@NamedQueries(@NamedQuery(name = "testQuery", query = "from ItemReadWrite where name = :name"))
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE, region = "item")
@NaturalIdCache
public class ItemReadWrite {
@Id
@GeneratedValue(generator = "increment")
@GenericGenerator(name = "increment", strategy = "increment")
private Long id;
private String name;
@NaturalId
private String nid;
@ElementCollection
@JoinTable(name = "Entries", joinColumns = @JoinColumn(name="Item_id"))
@Column(name = "entry", nullable = false)
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE, region = "item_entries")
private List<String> entries = new ArrayList<String>();
public ItemReadWrite() {
}
public ItemReadWrite(String name) {
this.name = name;
}
public String getNid() {
return nid;
}
public void setNid(String nid) {
this.nid = nid;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<String> getEntries() {
return entries;
}
}

@ -1,84 +0,0 @@
package org.redisson.hibernate;
import java.util.ArrayList;
import java.util.List;
import javax.persistence.Column;
import javax.persistence.ElementCollection;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import org.hibernate.annotations.Cache;
import org.hibernate.annotations.CacheConcurrencyStrategy;
import org.hibernate.annotations.GenericGenerator;
import org.hibernate.annotations.NaturalId;
import org.hibernate.annotations.NaturalIdCache;
/**
*
* @author Nikita Koksharov
*
*/
@Entity
@NamedQueries(@NamedQuery(name = "testQuery", query = "from ItemTransactional where name = :name"))
@Cache(usage = CacheConcurrencyStrategy.TRANSACTIONAL, region = "item")
@NaturalIdCache
public class ItemTransactional {
@Id
@GeneratedValue(generator = "increment")
@GenericGenerator(name = "increment", strategy = "increment")
private Long id;
private String name;
@NaturalId
private String nid;
@ElementCollection
@JoinTable(name = "Entries", joinColumns = @JoinColumn(name="Item_id"))
@Column(name = "entry", nullable = false)
@Cache(usage = CacheConcurrencyStrategy.TRANSACTIONAL, region = "item_entries")
private List<String> entries = new ArrayList<String>();
public ItemTransactional() {
}
public ItemTransactional(String name) {
this.name = name;
}
public String getNid() {
return nid;
}
public void setNid(String nid) {
this.nid = nid;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<String> getEntries() {
return entries;
}
}

@ -1,232 +0,0 @@
package org.redisson.hibernate;
import static org.assertj.core.api.Assertions.assertThat;
import java.util.Arrays;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.cfg.Configuration;
import org.hibernate.cfg.Environment;
import org.hibernate.stat.Statistics;
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.redisson.hibernate.RedissonRegionFactory;
/**
*
* @author Nikita Koksharov
*
*/
public class ReadWriteTest extends BaseCoreFunctionalTestCase {
@Override
protected Class<?>[] getAnnotatedClasses() {
return new Class[] { ItemReadWrite.class};
}
@Override
protected void configure(Configuration cfg) {
super.configure(cfg);
cfg.setProperty(Environment.DRIVER, org.h2.Driver.class.getName());
cfg.setProperty(Environment.URL, "jdbc:h2:mem:db1;DB_CLOSE_DELAY=-1;MVCC=TRUE");
cfg.setProperty(Environment.USER, "sa");
cfg.setProperty(Environment.PASS, "");
cfg.setProperty(Environment.CACHE_REGION_PREFIX, "");
cfg.setProperty(Environment.GENERATE_STATISTICS, "true");
cfg.setProperty(Environment.USE_SECOND_LEVEL_CACHE, "true");
cfg.setProperty(Environment.USE_QUERY_CACHE, "true");
cfg.setProperty(Environment.CACHE_REGION_FACTORY, RedissonRegionFactory.class.getName());
cfg.setProperty("hibernate.cache.redisson.item.eviction.max_entries", "100");
cfg.setProperty("hibernate.cache.redisson.item.expiration.time_to_live", "1500");
cfg.setProperty("hibernate.cache.redisson.item.expiration.max_idle_time", "1000");
}
@Before
public void before() {
sessionFactory().getCache().evictEntityRegions();
sessionFactory().getStatistics().clear();
}
@Test
public void testTimeToLive() throws InterruptedException {
Statistics stats = sessionFactory().getStatistics();
Long id = null;
Session s = openSession();
s.beginTransaction();
ItemReadWrite item = new ItemReadWrite( "data" );
id = (Long) s.save( item );
s.flush();
s.getTransaction().commit();
s.close();
Thread.sleep(900);
s = openSession();
s.beginTransaction();
item = (ItemReadWrite) s.get(ItemReadWrite.class, id);
Assert.assertEquals("data", item.getName());
s.getTransaction().commit();
s.close();
Assert.assertEquals(1, stats.getSecondLevelCacheStatistics("item").getHitCount());
Assert.assertEquals(0, stats.getSecondLevelCacheStatistics("item").getMissCount());
Thread.sleep(600);
s = openSession();
s.beginTransaction();
item = (ItemReadWrite) s.get(ItemReadWrite.class, id);
Assert.assertEquals("data", item.getName());
s.delete(item);
s.getTransaction().commit();
s.close();
Assert.assertEquals(1, stats.getSecondLevelCacheStatistics("item").getHitCount());
Assert.assertEquals(1, stats.getSecondLevelCacheStatistics("item").getMissCount());
}
@Test
public void testQuery() {
Statistics stats = sessionFactory().getStatistics();
Session s = openSession();
s.beginTransaction();
ItemReadWrite item = new ItemReadWrite("data");
item.getEntries().addAll(Arrays.asList("a", "b", "c"));
s.save(item);
s.flush();
s.getTransaction().commit();
s = openSession();
s.beginTransaction();
Query query = s.getNamedQuery("testQuery");
query.setCacheable(true);
query.setCacheRegion("myTestQuery");
query.setParameter("name", "data");
item = (ItemReadWrite) query.uniqueResult();
s.getTransaction().commit();
s.close();
Assert.assertEquals(1, stats.getSecondLevelCacheStatistics("myTestQuery").getPutCount());
s = openSession();
s.beginTransaction();
Query query2 = s.getNamedQuery("testQuery");
query2.setCacheable(true);
query2.setCacheRegion("myTestQuery");
query2.setParameter("name", "data");
item = (ItemReadWrite) query2.uniqueResult();
s.delete(item);
s.getTransaction().commit();
s.close();
Assert.assertEquals(1, stats.getSecondLevelCacheStatistics("myTestQuery").getHitCount());
stats.logSummary();
}
@Test
public void testCollection() {
Long id = null;
Statistics stats = sessionFactory().getStatistics();
Session s = openSession();
s.beginTransaction();
ItemReadWrite item = new ItemReadWrite("data");
item.getEntries().addAll(Arrays.asList("a", "b", "c"));
id = (Long) s.save(item);
s.flush();
s.getTransaction().commit();
s = openSession();
s.beginTransaction();
item = (ItemReadWrite) s.get(ItemReadWrite.class, id);
assertThat(item.getEntries()).containsExactly("a", "b", "c");
s.getTransaction().commit();
s.close();
Assert.assertEquals(1, stats.getSecondLevelCacheStatistics("item_entries").getPutCount());
s = openSession();
s.beginTransaction();
item = (ItemReadWrite) s.get(ItemReadWrite.class, id);
assertThat(item.getEntries()).containsExactly("a", "b", "c");
s.delete(item);
s.getTransaction().commit();
s.close();
Assert.assertEquals(1, stats.getSecondLevelCacheStatistics("item_entries").getHitCount());
}
@Test
public void testNaturalId() {
Statistics stats = sessionFactory().getStatistics();
Session s = openSession();
s.beginTransaction();
ItemReadWrite item = new ItemReadWrite("data");
item.setNid("123");
s.save(item);
s.flush();
s.getTransaction().commit();
Assert.assertEquals(1, stats.getSecondLevelCacheStatistics("item").getPutCount());
Assert.assertEquals(1, stats.getNaturalIdCacheStatistics("item##NaturalId").getPutCount());
s = openSession();
s.beginTransaction();
item = (ItemReadWrite) s.bySimpleNaturalId(ItemReadWrite.class).load("123");
assertThat(item).isNotNull();
s.delete(item);
s.getTransaction().commit();
s.close();
Assert.assertEquals(1, stats.getSecondLevelCacheStatistics("item").getHitCount());
Assert.assertEquals(1, stats.getNaturalIdCacheStatistics("item##NaturalId").getHitCount());
sessionFactory().getStatistics().logSummary();
}
@Test
public void testUpdateWithRefreshThenRollback() {
Statistics stats = sessionFactory().getStatistics();
Long id = null;
Session s = openSession();
s.beginTransaction();
ItemReadWrite item = new ItemReadWrite( "data" );
id = (Long) s.save( item );
s.flush();
s.getTransaction().commit();
Assert.assertEquals(1, stats.getSecondLevelCacheStatistics("item").getPutCount());
s = openSession();
s.beginTransaction();
item = (ItemReadWrite) s.get(ItemReadWrite.class, id);
item.setName("newdata");
s.update(item);
s.flush();
s.refresh(item);
s.getTransaction().rollback();
s.clear();
s.close();
s = openSession();
s.beginTransaction();
item = (ItemReadWrite) s.get(ItemReadWrite.class, id);
Assert.assertEquals("data", item.getName());
s.delete(item);
s.getTransaction().commit();
s.close();
Assert.assertEquals(1, stats.getSecondLevelCacheStatistics("item").getHitCount());
}
}

@ -1,181 +0,0 @@
package org.redisson.hibernate;
import static org.assertj.core.api.Assertions.assertThat;
import java.util.Arrays;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.cfg.Configuration;
import org.hibernate.cfg.Environment;
import org.hibernate.stat.Statistics;
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.redisson.hibernate.RedissonRegionFactory;
/**
*
* @author Nikita Koksharov
*
*/
public class TransactionalTest extends BaseCoreFunctionalTestCase {
@Override
protected Class<?>[] getAnnotatedClasses() {
return new Class[] { ItemTransactional.class};
}
@Override
protected void configure(Configuration cfg) {
super.configure(cfg);
cfg.setProperty(Environment.DRIVER, org.h2.Driver.class.getName());
cfg.setProperty(Environment.URL, "jdbc:h2:mem:db1;DB_CLOSE_DELAY=-1;MVCC=TRUE");
cfg.setProperty(Environment.USER, "sa");
cfg.setProperty(Environment.PASS, "");
cfg.setProperty(Environment.CACHE_REGION_PREFIX, "");
cfg.setProperty(Environment.GENERATE_STATISTICS, "true");
cfg.setProperty(Environment.USE_SECOND_LEVEL_CACHE, "true");
cfg.setProperty(Environment.USE_QUERY_CACHE, "true");
cfg.setProperty(Environment.CACHE_REGION_FACTORY, RedissonRegionFactory.class.getName());
}
@Before
public void before() {
sessionFactory().getCache().evictEntityRegions();
sessionFactory().getStatistics().clear();
}
@Test
public void testQuery() {
Statistics stats = sessionFactory().getStatistics();
Session s = openSession();
s.beginTransaction();
ItemTransactional item = new ItemTransactional("data");
item.getEntries().addAll(Arrays.asList("a", "b", "c"));
s.save(item);
s.flush();
s.getTransaction().commit();
s = openSession();
s.beginTransaction();
Query query = s.getNamedQuery("testQuery");
query.setCacheable(true);
query.setCacheRegion("myTestQuery");
query.setParameter("name", "data");
item = (ItemTransactional) query.uniqueResult();
s.getTransaction().commit();
s.close();
Assert.assertEquals(1, stats.getSecondLevelCacheStatistics("myTestQuery").getPutCount());
s = openSession();
s.beginTransaction();
Query query2 = s.getNamedQuery("testQuery");
query2.setCacheable(true);
query2.setCacheRegion("myTestQuery");
query2.setParameter("name", "data");
item = (ItemTransactional) query2.uniqueResult();
s.delete(item);
s.getTransaction().commit();
s.close();
Assert.assertEquals(1, stats.getSecondLevelCacheStatistics("myTestQuery").getHitCount());
stats.logSummary();
}
@Test
public void testCollection() {
Long id = null;
Statistics stats = sessionFactory().getStatistics();
Session s = openSession();
s.beginTransaction();
ItemTransactional item = new ItemTransactional("data");
item.getEntries().addAll(Arrays.asList("a", "b", "c"));
id = (Long) s.save(item);
s.flush();
s.getTransaction().commit();
s = openSession();
s.beginTransaction();
item = (ItemTransactional) s.get(ItemTransactional.class, id);
assertThat(item.getEntries()).containsExactly("a", "b", "c");
s.getTransaction().commit();
s.close();
Assert.assertEquals(1, stats.getSecondLevelCacheStatistics("item_entries").getPutCount());
s = openSession();
s.beginTransaction();
item = (ItemTransactional) s.get(ItemTransactional.class, id);
assertThat(item.getEntries()).containsExactly("a", "b", "c");
s.delete(item);
s.getTransaction().commit();
s.close();
Assert.assertEquals(1, stats.getSecondLevelCacheStatistics("item_entries").getHitCount());
}
@Test
public void testNaturalId() {
Statistics stats = sessionFactory().getStatistics();
Session s = openSession();
s.beginTransaction();
ItemTransactional item = new ItemTransactional("data");
item.setNid("123");
s.save(item);
s.flush();
s.getTransaction().commit();
Assert.assertEquals(1, stats.getSecondLevelCacheStatistics("item").getPutCount());
Assert.assertEquals(1, stats.getNaturalIdCacheStatistics("item##NaturalId").getPutCount());
s = openSession();
s.beginTransaction();
item = (ItemTransactional) s.bySimpleNaturalId(ItemTransactional.class).load("123");
assertThat(item).isNotNull();
s.delete(item);
s.getTransaction().commit();
s.close();
Assert.assertEquals(1, stats.getSecondLevelCacheStatistics("item").getHitCount());
Assert.assertEquals(1, stats.getNaturalIdCacheStatistics("item##NaturalId").getHitCount());
sessionFactory().getStatistics().logSummary();
}
@Test
public void testUpdateWithRefreshThenRollback() {
Statistics stats = sessionFactory().getStatistics();
Long id = null;
Session s = openSession();
s.beginTransaction();
ItemTransactional item = new ItemTransactional( "data" );
id = (Long) s.save( item );
s.flush();
s.getTransaction().commit();
Assert.assertEquals(1, stats.getSecondLevelCacheStatistics("item").getPutCount());
s = openSession();
s.beginTransaction();
item = (ItemTransactional) s.get(ItemTransactional.class, id);
item.setName("newdata");
s.update(item);
s.flush();
s.refresh(item);
s.getTransaction().rollback();
s.clear();
s.close();
Assert.assertEquals(1, stats.getSecondLevelCacheStatistics("item").getHitCount());
}
}

@ -1,8 +0,0 @@
{
"singleServerConfig":{
"address": "redis://127.0.0.1:6379"
},
"codec":{
"class":"org.redisson.codec.FstCodec"
}
}

@ -1,8 +0,0 @@
{
"singleServerConfig":{
"address": "redis://127.0.0.1:6379"
},
"codec":{
"class":"org.redisson.codec.FstCodec"
}
}

@ -1,104 +0,0 @@
<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.redisson</groupId>
<artifactId>redisson-hibernate</artifactId>
<version>3.11.7-SNAPSHOT</version>
<relativePath>../</relativePath>
</parent>
<artifactId>redisson-hibernate-5</artifactId>
<packaging>jar</packaging>
<name>Redisson/Hibernate-5.0.x-5.1.x</name>
<dependencies>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>5.1.16.Final</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-testing</artifactId>
<version>5.1.16.Final</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.javassist</groupId>
<artifactId>javassist</artifactId>
<version>3.25.0-GA</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.3.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-impl</artifactId>
<version>2.3.1</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<version>3.1.2</version>
<configuration>
<archive>
<manifestEntries>
<Build-Time>${maven.build.timestamp}</Build-Time>
<Automatic-Module-Name>redisson.hibernate5</Automatic-Module-Name>
</manifestEntries>
</archive>
</configuration>
</plugin>
<plugin>
<groupId>com.mycila</groupId>
<artifactId>license-maven-plugin</artifactId>
<version>3.0</version>
<configuration>
<basedir>${basedir}</basedir>
<header>${basedir}/../../header.txt</header>
<quiet>false</quiet>
<failIfMissing>true</failIfMissing>
<aggregate>false</aggregate>
<includes>
<include>src/main/java/org/redisson/</include>
</includes>
<excludes>
<exclude>target/**</exclude>
</excludes>
<useDefaultExcludes>true</useDefaultExcludes>
<mapping>
<java>JAVADOC_STYLE</java>
</mapping>
<strictCheck>true</strictCheck>
<useDefaultMapping>true</useDefaultMapping>
<encoding>UTF-8</encoding>
</configuration>
<executions>
<execution>
<goals>
<goal>check</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

@ -1,70 +0,0 @@
/**
* Copyright (c) 2013-2019 Nikita Koksharov
*
* 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.
*/
package org.redisson.hibernate;
import java.util.Properties;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import org.hibernate.cache.CacheException;
import org.hibernate.engine.jndi.internal.JndiServiceImpl;
import org.hibernate.internal.util.config.ConfigurationHelper;
import org.redisson.api.RedissonClient;
/**
* Hibernate Cache region factory based on Redisson.
* Uses Redisson instance located in JNDI.
*
* @author Nikita Koksharov
*
*/
public class JndiRedissonRegionFactory extends RedissonRegionFactory {
private static final long serialVersionUID = -4814502675083325567L;
public static final String JNDI_NAME = CONFIG_PREFIX + "jndi_name";
@Override
protected RedissonClient createRedissonClient(Properties properties) {
String jndiName = ConfigurationHelper.getString(JNDI_NAME, properties);
if (jndiName == null) {
throw new CacheException(JNDI_NAME + " property not set");
}
Properties jndiProperties = JndiServiceImpl.extractJndiProperties(properties);
InitialContext context = null;
try {
context = new InitialContext(jndiProperties);
return (RedissonClient) context.lookup(jndiName);
} catch (NamingException e) {
throw new CacheException("Unable to locate Redisson instance by name: " + jndiName, e);
} finally {
if (context != null) {
try {
context.close();
} catch (NamingException e) {
throw new CacheException("Unable to close JNDI context", e);
}
}
}
}
@Override
public void stop() {
}
}

@ -1,219 +0,0 @@
/**
* Copyright (c) 2013-2019 Nikita Koksharov
*
* 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.
*/
package org.redisson.hibernate;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;
import java.util.Properties;
import org.hibernate.boot.spi.SessionFactoryOptions;
import org.hibernate.cache.CacheException;
import org.hibernate.cache.spi.CacheDataDescription;
import org.hibernate.cache.spi.CollectionRegion;
import org.hibernate.cache.spi.EntityRegion;
import org.hibernate.cache.spi.NaturalIdRegion;
import org.hibernate.cache.spi.QueryResultsRegion;
import org.hibernate.cache.spi.RegionFactory;
import org.hibernate.cache.spi.TimestampsRegion;
import org.hibernate.cache.spi.access.AccessType;
import org.hibernate.cfg.Settings;
import org.hibernate.internal.util.config.ConfigurationHelper;
import org.jboss.logging.Logger;
import org.redisson.Redisson;
import org.redisson.api.RMapCache;
import org.redisson.api.RScript;
import org.redisson.api.RedissonClient;
import org.redisson.client.codec.LongCodec;
import org.redisson.config.Config;
import org.redisson.hibernate.region.RedissonCollectionRegion;
import org.redisson.hibernate.region.RedissonEntityRegion;
import org.redisson.hibernate.region.RedissonNaturalIdRegion;
import org.redisson.hibernate.region.RedissonQueryRegion;
import org.redisson.hibernate.region.RedissonTimestampsRegion;
/**
* Hibernate Cache region factory based on Redisson.
* Creates own Redisson instance during region start.
*
* @author Nikita Koksharov
*
*/public class RedissonRegionFactory implements RegionFactory {
private static final Logger log = Logger.getLogger( RedissonRegionFactory.class );
private static final long serialVersionUID = 3785315696581773811L;
public static final String QUERY_DEF = "query";
public static final String COLLECTION_DEF = "collection";
public static final String ENTITY_DEF = "entity";
public static final String NATURAL_ID_DEF = "naturalid";
public static final String TIMESTAMPS_DEF = "timestamps";
public static final String MAX_ENTRIES_SUFFIX = ".eviction.max_entries";
public static final String TTL_SUFFIX = ".expiration.time_to_live";
public static final String MAX_IDLE_SUFFIX = ".expiration.max_idle_time";
public static final String CONFIG_PREFIX = "hibernate.cache.redisson.";
public static final String REDISSON_CONFIG_PATH = CONFIG_PREFIX + "config";
protected RedissonClient redisson;
private Settings settings;
@Override
public void start(SessionFactoryOptions settings, Properties properties) throws CacheException {
this.redisson = createRedissonClient(properties);
this.settings = new Settings(settings);
}
protected RedissonClient createRedissonClient(Properties properties) {
Config config = null;
if (!properties.containsKey(REDISSON_CONFIG_PATH)) {
config = loadConfig(RedissonRegionFactory.class.getClassLoader(), "redisson.json");
if (config == null) {
config = loadConfig(RedissonRegionFactory.class.getClassLoader(), "redisson.yaml");
}
} else {
String configPath = ConfigurationHelper.getString(REDISSON_CONFIG_PATH, properties);
config = loadConfig(RedissonRegionFactory.class.getClassLoader(), configPath);
if (config == null) {
config = loadConfig(configPath);
}
}
if (config == null) {
throw new CacheException("Unable to locate Redisson configuration");
}
return Redisson.create(config);
}
private Config loadConfig(String configPath) {
try {
return Config.fromJSON(new File(configPath));
} catch (IOException e) {
// trying next format
try {
return Config.fromYAML(new File(configPath));
} catch (IOException e1) {
throw new CacheException("Can't parse default yaml config", e1);
}
}
}
private Config loadConfig(ClassLoader classLoader, String fileName) {
InputStream is = classLoader.getResourceAsStream(fileName);
if (is != null) {
try {
return Config.fromJSON(is);
} catch (IOException e) {
try {
is = classLoader.getResourceAsStream(fileName);
return Config.fromYAML(is);
} catch (IOException e1) {
throw new CacheException("Can't parse yaml config", e1);
}
}
}
return null;
}
@Override
public void stop() {
redisson.shutdown();
}
@Override
public boolean isMinimalPutsEnabledByDefault() {
return true;
}
@Override
public AccessType getDefaultAccessType() {
return AccessType.TRANSACTIONAL;
}
@Override
public long nextTimestamp() {
long time = System.currentTimeMillis() << 12;
return redisson.getScript(LongCodec.INSTANCE).eval(RScript.Mode.READ_WRITE,
"local currentTime = redis.call('get', KEYS[1]);"
+ "if currentTime == false then "
+ "redis.call('set', KEYS[1], ARGV[1]); "
+ "return ARGV[1]; "
+ "end;"
+ "local nextValue = math.max(tonumber(ARGV[1]), tonumber(currentTime) + 1); "
+ "redis.call('set', KEYS[1], nextValue); "
+ "return nextValue;",
RScript.ReturnType.INTEGER, Arrays.<Object>asList("redisson-hibernate-timestamp"), time);
}
@Override
public EntityRegion buildEntityRegion(String regionName, Properties properties, CacheDataDescription metadata)
throws CacheException {
log.debug("Building entity cache region: " + regionName);
RMapCache<Object, Object> mapCache = getCache(regionName, properties, ENTITY_DEF);
return new RedissonEntityRegion(mapCache, this, metadata, settings, properties, ENTITY_DEF);
}
@Override
public NaturalIdRegion buildNaturalIdRegion(String regionName, Properties properties, CacheDataDescription metadata)
throws CacheException {
log.debug("Building naturalId cache region: " + regionName);
RMapCache<Object, Object> mapCache = getCache(regionName, properties, NATURAL_ID_DEF);
return new RedissonNaturalIdRegion(mapCache, this, metadata, settings, properties, NATURAL_ID_DEF);
}
@Override
public CollectionRegion buildCollectionRegion(String regionName, Properties properties,
CacheDataDescription metadata) throws CacheException {
log.debug("Building collection cache region: " + regionName);
RMapCache<Object, Object> mapCache = getCache(regionName, properties, COLLECTION_DEF);
return new RedissonCollectionRegion(mapCache, this, metadata, settings, properties, COLLECTION_DEF);
}
@Override
public QueryResultsRegion buildQueryResultsRegion(String regionName, Properties properties) throws CacheException {
log.debug("Building query cache region: " + regionName);
RMapCache<Object, Object> mapCache = getCache(regionName, properties, QUERY_DEF);
return new RedissonQueryRegion(mapCache, this, properties, QUERY_DEF);
}
@Override
public TimestampsRegion buildTimestampsRegion(String regionName, Properties properties) throws CacheException {
log.debug("Building timestamps cache region: " + regionName);
RMapCache<Object, Object> mapCache = getCache(regionName, properties, TIMESTAMPS_DEF);
return new RedissonTimestampsRegion(mapCache, this, properties, TIMESTAMPS_DEF);
}
protected RMapCache<Object, Object> getCache(String regionName, Properties properties, String defaultKey) {
return redisson.getMapCache(regionName);
}
}

@ -1,42 +0,0 @@
/**
* Copyright (c) 2013-2019 Nikita Koksharov
*
* 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.
*/
package org.redisson.hibernate;
import java.util.Collections;
import org.hibernate.boot.registry.selector.SimpleStrategyRegistrationImpl;
import org.hibernate.boot.registry.selector.StrategyRegistration;
import org.hibernate.boot.registry.selector.StrategyRegistrationProvider;
import org.hibernate.cache.spi.RegionFactory;
/**
*
* @author Nikita Koksharov
*
*/
public class RedissonStrategyRegistrationProvider implements StrategyRegistrationProvider {
@Override
public Iterable<StrategyRegistration> getStrategyRegistrations() {
return Collections.<StrategyRegistration>singleton(new SimpleStrategyRegistrationImpl(
RegionFactory.class,
RedissonRegionFactory.class,
"redisson",
RedissonRegionFactory.class.getName(),
RedissonRegionFactory.class.getSimpleName()));
}
}

@ -1,179 +0,0 @@
/**
* Copyright (c) 2013-2019 Nikita Koksharov
*
* 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.
*/
package org.redisson.hibernate.region;
import java.util.Collections;
import java.util.Map;
import java.util.Properties;
import java.util.concurrent.TimeUnit;
import org.hibernate.cache.CacheException;
import org.hibernate.cache.spi.CacheDataDescription;
import org.hibernate.cache.spi.GeneralDataRegion;
import org.hibernate.cache.spi.RegionFactory;
import org.hibernate.cache.spi.TransactionalDataRegion;
import org.hibernate.engine.spi.SessionImplementor;
import org.redisson.api.RMapCache;
import org.redisson.hibernate.RedissonRegionFactory;
/**
*
* @author Nikita Koksharov
*
*/
public class BaseRegion implements TransactionalDataRegion, GeneralDataRegion {
final RMapCache<Object, Object> mapCache;
final RegionFactory regionFactory;
final CacheDataDescription metadata;
int ttl;
int maxIdle;
public BaseRegion(RMapCache<Object, Object> mapCache, RegionFactory regionFactory, CacheDataDescription metadata, Properties properties, String defaultKey) {
super();
this.mapCache = mapCache;
this.regionFactory = regionFactory;
this.metadata = metadata;
String maxEntries = getProperty(properties, mapCache.getName(), defaultKey, RedissonRegionFactory.MAX_ENTRIES_SUFFIX);
if (maxEntries != null) {
mapCache.setMaxSize(Integer.valueOf(maxEntries));
}
String timeToLive = getProperty(properties, mapCache.getName(), defaultKey, RedissonRegionFactory.TTL_SUFFIX);
if (timeToLive != null) {
ttl = Integer.valueOf(timeToLive);
}
String maxIdleTime = getProperty(properties, mapCache.getName(), defaultKey, RedissonRegionFactory.MAX_IDLE_SUFFIX);
if (maxIdleTime != null) {
maxIdle = Integer.valueOf(maxIdleTime);
}
}
private String getProperty(Properties properties, String name, String defaultKey, String suffix) {
String value = properties.getProperty(RedissonRegionFactory.CONFIG_PREFIX + name + suffix);
if (value != null) {
return value;
}
String defValue = properties.getProperty(RedissonRegionFactory.CONFIG_PREFIX + defaultKey + suffix);
if (defValue != null) {
return defValue;
}
return null;
}
@Override
public boolean isTransactionAware() {
// TODO Auto-generated method stub
return false;
}
@Override
public CacheDataDescription getCacheDataDescription() {
return metadata;
}
@Override
public String getName() {
return mapCache.getName();
}
@Override
public void destroy() throws CacheException {
try {
mapCache.destroy();
} catch (Exception e) {
throw new CacheException(e);
}
}
@Override
public boolean contains(Object key) {
try {
return mapCache.containsKey(key);
} catch (Exception e) {
throw new CacheException(e);
}
}
@Override
public long getSizeInMemory() {
return mapCache.sizeInMemory();
}
@Override
public long getElementCountInMemory() {
return mapCache.size();
}
@Override
public long getElementCountOnDisk() {
return -1;
}
@Override
public Map<?, ?> toMap() {
return Collections.unmodifiableMap(mapCache);
}
@Override
public long nextTimestamp() {
return regionFactory.nextTimestamp();
}
@Override
public int getTimeout() {
// 60 seconds (normalized value)
return (1 << 12) * 60000;
}
@Override
public Object get(SessionImplementor session, Object key) throws CacheException {
try {
return mapCache.get(key);
} catch (Exception e) {
throw new CacheException(e);
}
}
@Override
public void put(SessionImplementor session, Object key, Object value) throws CacheException {
try {
mapCache.fastPut(key, value, ttl, TimeUnit.MILLISECONDS, maxIdle, TimeUnit.MILLISECONDS);
} catch (Exception e) {
throw new CacheException(e);
}
}
@Override
public void evict(Object key) throws CacheException {
try {
mapCache.fastRemove(key);
} catch (Exception e) {
throw new CacheException(e);
}
}
@Override
public void evictAll() throws CacheException {
try {
mapCache.clear();
} catch (Exception e) {
throw new CacheException(e);
}
}
}

@ -1,66 +0,0 @@
/**
* Copyright (c) 2013-2019 Nikita Koksharov
*
* 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.
*/
package org.redisson.hibernate.region;
import java.util.Properties;
import org.hibernate.cache.CacheException;
import org.hibernate.cache.spi.CacheDataDescription;
import org.hibernate.cache.spi.CollectionRegion;
import org.hibernate.cache.spi.RegionFactory;
import org.hibernate.cache.spi.access.AccessType;
import org.hibernate.cache.spi.access.CollectionRegionAccessStrategy;
import org.hibernate.cfg.Settings;
import org.redisson.api.RMapCache;
import org.redisson.hibernate.strategy.NonStrictReadWriteCollectionRegionAccessStrategy;
import org.redisson.hibernate.strategy.ReadOnlyCollectionRegionAccessStrategy;
import org.redisson.hibernate.strategy.ReadWriteCollectionRegionAccessStrategy;
import org.redisson.hibernate.strategy.TransactionalCollectionRegionAccessStrategy;
/**
*
* @author Nikita Koksharov
*
*/
public class RedissonCollectionRegion extends BaseRegion implements CollectionRegion {
private final Settings settings;
public RedissonCollectionRegion(RMapCache<Object, Object> mapCache, RegionFactory regionFactory,
CacheDataDescription metadata, Settings settings, Properties properties, String defaultKey) {
super(mapCache, regionFactory, metadata, properties, defaultKey);
this.settings = settings;
}
@Override
public CollectionRegionAccessStrategy buildAccessStrategy(AccessType accessType) throws CacheException {
if (accessType == AccessType.READ_ONLY) {
return new ReadOnlyCollectionRegionAccessStrategy(settings, this);
}
if (accessType == AccessType.READ_WRITE) {
return new ReadWriteCollectionRegionAccessStrategy(settings, this, mapCache);
}
if (accessType == AccessType.NONSTRICT_READ_WRITE) {
return new NonStrictReadWriteCollectionRegionAccessStrategy(settings, this);
}
if (accessType == AccessType.TRANSACTIONAL) {
return new TransactionalCollectionRegionAccessStrategy(settings, this);
}
throw new CacheException("Unsupported access strategy: " + accessType);
}
}

@ -1,66 +0,0 @@
/**
* Copyright (c) 2013-2019 Nikita Koksharov
*
* 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.
*/
package org.redisson.hibernate.region;
import java.util.Properties;
import org.hibernate.cache.CacheException;
import org.hibernate.cache.spi.CacheDataDescription;
import org.hibernate.cache.spi.EntityRegion;
import org.hibernate.cache.spi.RegionFactory;
import org.hibernate.cache.spi.access.AccessType;
import org.hibernate.cache.spi.access.EntityRegionAccessStrategy;
import org.hibernate.cfg.Settings;
import org.redisson.api.RMapCache;
import org.redisson.hibernate.strategy.NonStrictReadWriteEntityRegionAccessStrategy;
import org.redisson.hibernate.strategy.ReadOnlyEntityRegionAccessStrategy;
import org.redisson.hibernate.strategy.ReadWriteEntityRegionAccessStrategy;
import org.redisson.hibernate.strategy.TransactionalEntityRegionAccessStrategy;
/**
*
* @author Nikita Koksharov
*
*/
public class RedissonEntityRegion extends BaseRegion implements EntityRegion {
private final Settings settings;
public RedissonEntityRegion(RMapCache<Object, Object> mapCache, RegionFactory regionFactory,
CacheDataDescription metadata, Settings settings, Properties properties, String defaultKey) {
super(mapCache, regionFactory, metadata, properties, defaultKey);
this.settings = settings;
}
@Override
public EntityRegionAccessStrategy buildAccessStrategy(AccessType accessType) throws CacheException {
if (accessType == AccessType.READ_ONLY) {
return new ReadOnlyEntityRegionAccessStrategy(settings, this);
}
if (accessType == AccessType.READ_WRITE) {
return new ReadWriteEntityRegionAccessStrategy(settings, this, mapCache);
}
if (accessType == AccessType.NONSTRICT_READ_WRITE) {
return new NonStrictReadWriteEntityRegionAccessStrategy(settings, this);
}
if (accessType == AccessType.TRANSACTIONAL) {
return new TransactionalEntityRegionAccessStrategy(settings, this);
}
throw new CacheException("Unsupported access strategy: " + accessType);
}
}

@ -1,66 +0,0 @@
/**
* Copyright (c) 2013-2019 Nikita Koksharov
*
* 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.
*/
package org.redisson.hibernate.region;
import java.util.Properties;
import org.hibernate.cache.CacheException;
import org.hibernate.cache.spi.CacheDataDescription;
import org.hibernate.cache.spi.NaturalIdRegion;
import org.hibernate.cache.spi.RegionFactory;
import org.hibernate.cache.spi.access.AccessType;
import org.hibernate.cache.spi.access.NaturalIdRegionAccessStrategy;
import org.hibernate.cfg.Settings;
import org.redisson.api.RMapCache;
import org.redisson.hibernate.strategy.NonStrictReadWriteNaturalIdRegionAccessStrategy;
import org.redisson.hibernate.strategy.ReadOnlyNaturalIdRegionAccessStrategy;
import org.redisson.hibernate.strategy.ReadWriteNaturalIdRegionAccessStrategy;
import org.redisson.hibernate.strategy.TransactionalNaturalIdRegionAccessStrategy;
/**
*
* @author Nikita Koksharov
*
*/
public class RedissonNaturalIdRegion extends BaseRegion implements NaturalIdRegion {
private final Settings settings;
public RedissonNaturalIdRegion(RMapCache<Object, Object> mapCache, RegionFactory regionFactory,
CacheDataDescription metadata, Settings settings, Properties properties, String defaultKey) {
super(mapCache, regionFactory, metadata, properties, defaultKey);
this.settings = settings;
}
@Override
public NaturalIdRegionAccessStrategy buildAccessStrategy(AccessType accessType) throws CacheException {
if (accessType == AccessType.READ_ONLY) {
return new ReadOnlyNaturalIdRegionAccessStrategy(settings, this);
}
if (accessType == AccessType.READ_WRITE) {
return new ReadWriteNaturalIdRegionAccessStrategy(settings, this, mapCache);
}
if (accessType == AccessType.NONSTRICT_READ_WRITE) {
return new NonStrictReadWriteNaturalIdRegionAccessStrategy(settings, this);
}
if (accessType == AccessType.TRANSACTIONAL) {
return new TransactionalNaturalIdRegionAccessStrategy(settings, this);
}
throw new CacheException("Unsupported access strategy: " + accessType);
}
}

@ -1,36 +0,0 @@
/**
* Copyright (c) 2013-2019 Nikita Koksharov
*
* 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.
*/
package org.redisson.hibernate.region;
import java.util.Properties;
import org.hibernate.cache.spi.QueryResultsRegion;
import org.hibernate.cache.spi.RegionFactory;
import org.redisson.api.RMapCache;
/**
*
* @author Nikita Koksharov
*
*/
public class RedissonQueryRegion extends BaseRegion implements QueryResultsRegion {
public RedissonQueryRegion(RMapCache<Object, Object> mapCache,
RegionFactory regionFactory, Properties properties, String defaultKey) {
super(mapCache, regionFactory, null, properties, defaultKey);
}
}

@ -1,36 +0,0 @@
/**
* Copyright (c) 2013-2019 Nikita Koksharov
*
* 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.
*/
package org.redisson.hibernate.region;
import java.util.Properties;
import org.hibernate.cache.spi.RegionFactory;
import org.hibernate.cache.spi.TimestampsRegion;
import org.redisson.api.RMapCache;
/**
*
* @author Nikita Koksharov
*
*/
public class RedissonTimestampsRegion extends BaseRegion implements TimestampsRegion {
public RedissonTimestampsRegion(RMapCache<Object, Object> mapCache,
RegionFactory regionFactory, Properties properties, String defaultKey) {
super(mapCache, regionFactory, null, properties, defaultKey);
}
}

@ -1,356 +0,0 @@
/**
* Copyright (c) 2013-2019 Nikita Koksharov
*
* 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.
*/
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2010-2011, Red Hat Inc. or third-party contributors as
* indicated by the @author tags or express copyright attribution
* statements applied by the authors. All third-party contributions are
* distributed under license by Red Hat Inc.
*
* This copyrighted material is made available to anyone wishing to use, modify,
* copy, or redistribute it subject to the terms and conditions of the GNU
* Lesser General Public License, as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this distribution; if not, write to:
* Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
package org.redisson.hibernate.strategy;
import java.io.Serializable;
import java.util.Comparator;
import java.util.UUID;
import java.util.concurrent.atomic.AtomicLong;
import org.hibernate.cache.CacheException;
import org.hibernate.cache.spi.GeneralDataRegion;
import org.hibernate.cache.spi.TransactionalDataRegion;
import org.hibernate.cache.spi.access.SoftLock;
import org.hibernate.cfg.Settings;
import org.hibernate.engine.spi.SessionImplementor;
import org.redisson.api.RLock;
import org.redisson.api.RMapCache;
/**
*
* @author Nikita Koksharov
* @author Strong Liu
*
*/
public class AbstractReadWriteAccessStrategy extends BaseRegionAccessStrategy {
private final UUID uuid = UUID.randomUUID();
private final AtomicLong nextLockId = new AtomicLong();
final RMapCache<Object, Object> mapCache;
public AbstractReadWriteAccessStrategy(Settings settings, GeneralDataRegion region, RMapCache<Object, Object> mapCache) {
super(settings, region);
this.mapCache = mapCache;
}
@Override
public Object get(SessionImplementor session, Object key, long txTimestamp) throws CacheException {
RLock readLock = mapCache.getReadWriteLock(key).readLock();
readLock.lock();
try {
Lockable item = (Lockable) region.get(session, key);
if (item != null && item.isReadable(txTimestamp)) {
return item.getValue();
} else {
return null;
}
} finally {
readLock.unlock();
}
}
@Override
public boolean putFromLoad(SessionImplementor session, Object key, Object value, long txTimestamp, Object version, boolean minimalPutOverride)
throws CacheException {
RLock writeLock = mapCache.getReadWriteLock(key).writeLock();
writeLock.lock();
try {
Lockable item = (Lockable) region.get(session, key);
Comparator<Object> comparator = ((TransactionalDataRegion)region).getCacheDataDescription().getVersionComparator();
boolean writeable = item == null || item.isWriteable(txTimestamp, version, comparator);
if (writeable) {
region.put(session, key, new Item(value, version, region.nextTimestamp()));
return true;
}
return false;
} finally {
writeLock.unlock();
}
}
@Override
public SoftLock lockItem(SessionImplementor session, Object key, Object version) throws CacheException {
RLock writeLock = mapCache.getReadWriteLock(key).writeLock();
writeLock.lock();
try {
Lockable item = (Lockable) region.get(session, key);
long timeout = region.nextTimestamp() + region.getTimeout();
Lock lock;
if (item == null) {
lock = new Lock(timeout, uuid, nextLockId.getAndIncrement(), version);
} else {
lock = item.lock(timeout, uuid, nextLockId.getAndIncrement());
}
region.put(session, key, lock);
return lock;
} finally {
writeLock.unlock();
}
}
@Override
public void unlockItem(SessionImplementor session, Object key, SoftLock lock) throws CacheException {
RLock writeLock = mapCache.getReadWriteLock(key).writeLock();
writeLock.lock();
try {
Lockable item = (Lockable) region.get(session, key);
if (item != null && item.isUnlockable(lock)) {
decrementLock(session, key, (Lock)item);
} else {
handleLockExpiry(session, key, item);
}
} finally {
writeLock.unlock();
}
}
/**
* Unlock and re-put the given key, lock combination.
*/
protected void decrementLock(SessionImplementor session, Object key, Lock lock) {
lock.unlock(region.nextTimestamp());
region.put(session, key, lock);
}
/**
* Handle the timeout of a previous lock mapped to this key
*/
protected void handleLockExpiry(SessionImplementor session, Object key, Lockable lock) {
long ts = region.nextTimestamp() + region.getTimeout();
// create new lock that times out immediately
Lock newLock = new Lock(ts, uuid, nextLockId.getAndIncrement(), null);
newLock.unlock(ts);
region.put(session, key, newLock);
}
/**
* Interface type implemented by all wrapper objects in the cache.
*/
public interface Lockable {
/**
* Returns <code>true</code> if the enclosed value can be read by a transaction started at the given time.
*/
public boolean isReadable(long txTimestamp);
/**
* Returns <code>true</code> if the enclosed value can be replaced with one of the given version by a
* transaction started at the given time.
*/
public boolean isWriteable(long txTimestamp, Object version, Comparator<Object> versionComparator);
/**
* Returns the enclosed value.
*/
public Object getValue();
/**
* Returns <code>true</code> if the given lock can be unlocked using the given SoftLock instance as a handle.
*/
public boolean isUnlockable(SoftLock lock);
/**
* Locks this entry, stamping it with the UUID and lockId given, with the lock timeout occuring at the specified
* time. The returned Lock object can be used to unlock the entry in the future.
*/
public Lock lock(long timeout, UUID uuid, long lockId);
}
/**
* Wrapper type representing unlocked items.
*/
public final static class Item implements Serializable, Lockable {
private static final long serialVersionUID = 1L;
private Object value;
private Object version;
private long timestamp;
/**
* Creates an unlocked item wrapping the given value with a version and creation timestamp.
*/
public Item(Object value, Object version, long timestamp) {
this.value = value;
this.version = version;
this.timestamp = timestamp;
}
@Override
public boolean isReadable(long txTimestamp) {
return txTimestamp > timestamp;
}
@Override
public boolean isWriteable(long txTimestamp, Object newVersion, Comparator<Object> versionComparator) {
return version != null && versionComparator.compare( version, newVersion ) < 0;
}
@Override
public Object getValue() {
return value;
}
@Override
public boolean isUnlockable(SoftLock lock) {
return false;
}
@Override
public Lock lock(long timeout, UUID uuid, long lockId) {
return new Lock(timeout, uuid, lockId, version);
}
}
/**
* Wrapper type representing locked items.
*/
public final static class Lock implements Serializable, Lockable, SoftLock {
private static final long serialVersionUID = 2L;
private UUID sourceUuid;
private long lockId;
private Object version;
private long timeout;
private boolean concurrent;
private int multiplicity = 1;
private long unlockTimestamp;
/**
* Creates a locked item with the given identifiers and object version.
*/
public Lock(long timeout, UUID sourceUuid, long lockId, Object version) {
this.timeout = timeout;
this.lockId = lockId;
this.version = version;
this.sourceUuid = sourceUuid;
}
@Override
public boolean isReadable(long txTimestamp) {
return false;
}
@Override
public boolean isWriteable(long txTimestamp, Object newVersion, Comparator versionComparator) {
if ( txTimestamp > timeout ) {
// if timedout then allow write
return true;
}
if ( multiplicity > 0 ) {
// if still locked then disallow write
return false;
}
return version == null ? txTimestamp > unlockTimestamp : versionComparator.compare(
version,
newVersion
) < 0;
}
@Override
public Object getValue() {
return null;
}
@Override
public boolean isUnlockable(SoftLock lock) {
return equals( lock );
}
@Override
public boolean equals(Object o) {
if ( o == this ) {
return true;
}
else if ( o instanceof Lock ) {
return ( lockId == ( (Lock) o ).lockId ) && sourceUuid.equals( ( (Lock) o ).sourceUuid );
}
else {
return false;
}
}
@Override
public int hashCode() {
int hash = ( sourceUuid != null ? sourceUuid.hashCode() : 0 );
int temp = (int) lockId;
for ( int i = 1; i < Long.SIZE / Integer.SIZE; i++ ) {
temp ^= ( lockId >>> ( i * Integer.SIZE ) );
}
return hash + temp;
}
/**
* Returns true if this Lock has been concurrently locked by more than one transaction.
*/
public boolean wasLockedConcurrently() {
return concurrent;
}
@Override
public Lock lock(long timeout, UUID uuid, long lockId) {
concurrent = true;
multiplicity++;
this.timeout = timeout;
return this;
}
/**
* Unlocks this Lock, and timestamps the unlock event.
*/
public void unlock(long timestamp) {
if ( --multiplicity == 0 ) {
unlockTimestamp = timestamp;
}
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder( "Lock Source-UUID:" + sourceUuid + " Lock-ID:" + lockId );
return sb.toString();
}
}
}

@ -1,74 +0,0 @@
/**
* Copyright (c) 2013-2019 Nikita Koksharov
*
* 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.
*/
package org.redisson.hibernate.strategy;
import org.hibernate.cache.CacheException;
import org.hibernate.cache.spi.GeneralDataRegion;
import org.hibernate.cache.spi.access.RegionAccessStrategy;
import org.hibernate.cache.spi.access.SoftLock;
import org.hibernate.cfg.Settings;
import org.hibernate.engine.spi.SessionImplementor;
/**
*
* @author Nikita Koksharov
*
*/
abstract class BaseRegionAccessStrategy implements RegionAccessStrategy {
final GeneralDataRegion region;
final Settings settings;
BaseRegionAccessStrategy(Settings settings, GeneralDataRegion region) {
this.settings = settings;
this.region = region;
}
@Override
public boolean putFromLoad(SessionImplementor session, Object key, Object value, long txTimestamp, Object version) throws CacheException {
return putFromLoad(session, key, value, txTimestamp, version, settings.isMinimalPutsEnabled() );
}
@Override
public SoftLock lockRegion() throws CacheException {
return null;
}
@Override
public void unlockRegion(SoftLock lock) throws CacheException {
region.evictAll();
}
@Override
public void remove(SessionImplementor session, Object key) throws CacheException {
}
@Override
public void removeAll() throws CacheException {
region.evictAll();
}
@Override
public void evict(Object key) throws CacheException {
region.evict(key);
}
@Override
public void evictAll() throws CacheException {
region.evictAll();
}
}

@ -1,87 +0,0 @@
/**
* Copyright (c) 2013-2019 Nikita Koksharov
*
* 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.
*/
package org.redisson.hibernate.strategy;
import org.hibernate.cache.CacheException;
import org.hibernate.cache.internal.DefaultCacheKeysFactory;
import org.hibernate.cache.spi.CollectionRegion;
import org.hibernate.cache.spi.GeneralDataRegion;
import org.hibernate.cache.spi.access.CollectionRegionAccessStrategy;
import org.hibernate.cache.spi.access.SoftLock;
import org.hibernate.cfg.Settings;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.engine.spi.SessionImplementor;
import org.hibernate.persister.collection.CollectionPersister;
/**
*
* @author Nikita Koksharov
*
*/
public class NonStrictReadWriteCollectionRegionAccessStrategy extends BaseRegionAccessStrategy implements CollectionRegionAccessStrategy {
public NonStrictReadWriteCollectionRegionAccessStrategy(Settings settings, GeneralDataRegion region) {
super(settings, region);
}
@Override
public CollectionRegion getRegion() {
return (CollectionRegion) region;
}
@Override
public Object get(SessionImplementor session, Object key, long txTimestamp) throws CacheException {
return region.get(session, key);
}
@Override
public boolean putFromLoad(SessionImplementor session, Object key, Object value, long txTimestamp, Object version, boolean minimalPutOverride)
throws CacheException {
if (minimalPutOverride && region.contains(key)) {
return false;
}
region.put(session, key, value);
return true;
}
@Override
public SoftLock lockItem(SessionImplementor session, Object key, Object version) throws CacheException {
return null;
}
@Override
public void unlockItem(SessionImplementor session, Object key, SoftLock lock) throws CacheException {
evict(key);
}
@Override
public void remove(SessionImplementor session, Object key) throws CacheException {
evict(key);
}
@Override
public Object generateCacheKey(Object id, CollectionPersister persister, SessionFactoryImplementor factory,
String tenantIdentifier) {
return DefaultCacheKeysFactory.staticCreateCollectionKey( id, persister, factory, tenantIdentifier );
}
@Override
public Object getCacheKeyId(Object cacheKey) {
return DefaultCacheKeysFactory.staticGetCollectionId( cacheKey );
}
}

@ -1,110 +0,0 @@
/**
* Copyright (c) 2013-2019 Nikita Koksharov
*
* 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.
*/
package org.redisson.hibernate.strategy;
import org.hibernate.cache.CacheException;
import org.hibernate.cache.internal.DefaultCacheKeysFactory;
import org.hibernate.cache.spi.EntityRegion;
import org.hibernate.cache.spi.GeneralDataRegion;
import org.hibernate.cache.spi.access.EntityRegionAccessStrategy;
import org.hibernate.cache.spi.access.SoftLock;
import org.hibernate.cfg.Settings;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.engine.spi.SessionImplementor;
import org.hibernate.persister.entity.EntityPersister;
/**
*
* @author Nikita Koksharov
*
*/
public class NonStrictReadWriteEntityRegionAccessStrategy extends BaseRegionAccessStrategy implements EntityRegionAccessStrategy {
public NonStrictReadWriteEntityRegionAccessStrategy(Settings settings, GeneralDataRegion region) {
super(settings, region);
}
@Override
public Object get(SessionImplementor session, Object key, long txTimestamp) throws CacheException {
return region.get(session, key);
}
@Override
public boolean putFromLoad(SessionImplementor session, Object key, Object value, long txTimestamp, Object version, boolean minimalPutOverride)
throws CacheException {
if (minimalPutOverride && region.contains(key)) {
return false;
}
region.put(session, key, value);
return true;
}
@Override
public SoftLock lockItem(SessionImplementor session, Object key, Object version) throws CacheException {
return null;
}
@Override
public void unlockItem(SessionImplementor session, Object key, SoftLock lock) throws CacheException {
evict(key);
}
@Override
public EntityRegion getRegion() {
return (EntityRegion) region;
}
@Override
public boolean insert(SessionImplementor session, Object key, Object value, Object version) throws CacheException {
return false;
}
@Override
public boolean afterInsert(SessionImplementor session, Object key, Object value, Object version) throws CacheException {
return false;
}
@Override
public boolean update(SessionImplementor session, Object key, Object value, Object currentVersion, Object previousVersion)
throws CacheException {
remove(session, key);
return false;
}
@Override
public boolean afterUpdate(SessionImplementor session, Object key, Object value, Object currentVersion, Object previousVersion, SoftLock lock)
throws CacheException {
unlockItem(session, key, lock);
return false;
}
@Override
public void remove(SessionImplementor session, Object key) throws CacheException {
evict(key);
}
@Override
public Object generateCacheKey(Object id, EntityPersister persister, SessionFactoryImplementor factory, String tenantIdentifier) {
return DefaultCacheKeysFactory.staticCreateEntityKey( id, persister, factory, tenantIdentifier );
}
@Override
public Object getCacheKeyId(Object cacheKey) {
return DefaultCacheKeysFactory.staticGetEntityId( cacheKey );
}
}

@ -1,107 +0,0 @@
/**
* Copyright (c) 2013-2019 Nikita Koksharov
*
* 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.
*/
package org.redisson.hibernate.strategy;
import org.hibernate.cache.CacheException;
import org.hibernate.cache.internal.DefaultCacheKeysFactory;
import org.hibernate.cache.spi.GeneralDataRegion;
import org.hibernate.cache.spi.NaturalIdRegion;
import org.hibernate.cache.spi.access.NaturalIdRegionAccessStrategy;
import org.hibernate.cache.spi.access.SoftLock;
import org.hibernate.cfg.Settings;
import org.hibernate.engine.spi.SessionImplementor;
import org.hibernate.persister.entity.EntityPersister;
/**
*
* @author Nikita Koksharov
*
*/
public class NonStrictReadWriteNaturalIdRegionAccessStrategy extends BaseRegionAccessStrategy implements NaturalIdRegionAccessStrategy {
public NonStrictReadWriteNaturalIdRegionAccessStrategy(Settings settings, GeneralDataRegion region) {
super(settings, region);
}
@Override
public Object get(SessionImplementor session, Object key, long txTimestamp) throws CacheException {
return region.get(session, key);
}
@Override
public boolean putFromLoad(SessionImplementor session, Object key, Object value, long txTimestamp, Object version, boolean minimalPutOverride)
throws CacheException {
if (minimalPutOverride && region.contains(key)) {
return false;
}
region.put(session, key, value);
return true;
}
@Override
public SoftLock lockItem(SessionImplementor session, Object key, Object version) throws CacheException {
return null;
}
@Override
public void unlockItem(SessionImplementor session, Object key, SoftLock lock) throws CacheException {
evict(key);
}
@Override
public NaturalIdRegion getRegion() {
return (NaturalIdRegion) region;
}
@Override
public boolean insert(SessionImplementor session, Object key, Object value) throws CacheException {
return false;
}
@Override
public boolean afterInsert(SessionImplementor session, Object key, Object value) throws CacheException {
return false;
}
@Override
public boolean update(SessionImplementor session, Object key, Object value) throws CacheException {
remove(session, key);
return false;
}
@Override
public boolean afterUpdate(SessionImplementor session, Object key, Object value, SoftLock lock) throws CacheException {
unlockItem(session, key, lock);
return false;
}
@Override
public void remove(SessionImplementor session, Object key) throws CacheException {
region.evict(key);
}
@Override
public Object generateCacheKey(Object[] naturalIdValues, EntityPersister persister, SessionImplementor session) {
return DefaultCacheKeysFactory.staticCreateNaturalIdKey(naturalIdValues, persister, session);
}
@Override
public Object[] getNaturalIdValues(Object cacheKey) {
return DefaultCacheKeysFactory.staticGetNaturalIdValues(cacheKey);
}
}

@ -1,80 +0,0 @@
/**
* Copyright (c) 2013-2019 Nikita Koksharov
*
* 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.
*/
package org.redisson.hibernate.strategy;
import org.hibernate.cache.CacheException;
import org.hibernate.cache.internal.DefaultCacheKeysFactory;
import org.hibernate.cache.spi.CollectionRegion;
import org.hibernate.cache.spi.GeneralDataRegion;
import org.hibernate.cache.spi.access.CollectionRegionAccessStrategy;
import org.hibernate.cache.spi.access.SoftLock;
import org.hibernate.cfg.Settings;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.engine.spi.SessionImplementor;
import org.hibernate.persister.collection.CollectionPersister;
/**
*
* @author Nikita Koksharov
*
*/
public class ReadOnlyCollectionRegionAccessStrategy extends BaseRegionAccessStrategy implements CollectionRegionAccessStrategy {
public ReadOnlyCollectionRegionAccessStrategy(Settings settings, GeneralDataRegion region) {
super(settings, region);
}
@Override
public CollectionRegion getRegion() {
return (CollectionRegion) region;
}
@Override
public Object get(SessionImplementor session, Object key, long txTimestamp) throws CacheException {
return region.get(session, key);
}
@Override
public boolean putFromLoad(SessionImplementor session, Object key, Object value, long txTimestamp, Object version, boolean minimalPutOverride)
throws CacheException {
if (minimalPutOverride && region.contains(key)) {
return false;
}
region.put(session, key, value);
return true;
}
@Override
public SoftLock lockItem(SessionImplementor session, Object key, Object version) throws CacheException {
return null;
}
@Override
public void unlockItem(SessionImplementor session, Object key, SoftLock lock) throws CacheException {
}
@Override
public Object generateCacheKey(Object id, CollectionPersister persister, SessionFactoryImplementor factory, String tenantIdentifier) {
return DefaultCacheKeysFactory.staticCreateCollectionKey( id, persister, factory, tenantIdentifier );
}
@Override
public Object getCacheKeyId(Object cacheKey) {
return DefaultCacheKeysFactory.staticGetCollectionId(cacheKey);
}
}

@ -1,104 +0,0 @@
/**
* Copyright (c) 2013-2019 Nikita Koksharov
*
* 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.
*/
package org.redisson.hibernate.strategy;
import org.hibernate.cache.CacheException;
import org.hibernate.cache.internal.DefaultCacheKeysFactory;
import org.hibernate.cache.spi.EntityRegion;
import org.hibernate.cache.spi.GeneralDataRegion;
import org.hibernate.cache.spi.access.EntityRegionAccessStrategy;
import org.hibernate.cache.spi.access.SoftLock;
import org.hibernate.cfg.Settings;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.engine.spi.SessionImplementor;
import org.hibernate.persister.entity.EntityPersister;
/**
*
* @author Nikita Koksharov
*
*/
public class ReadOnlyEntityRegionAccessStrategy extends BaseRegionAccessStrategy implements EntityRegionAccessStrategy {
public ReadOnlyEntityRegionAccessStrategy(Settings settings, GeneralDataRegion region) {
super(settings, region);
}
@Override
public Object get(SessionImplementor session, Object key, long txTimestamp) throws CacheException {
return region.get(session, key);
}
@Override
public boolean putFromLoad(SessionImplementor session, Object key, Object value, long txTimestamp, Object version, boolean minimalPutOverride)
throws CacheException {
if (minimalPutOverride && region.contains(key)) {
return false;
}
region.put(session, key, value);
return true;
}
@Override
public SoftLock lockItem(SessionImplementor session, Object key, Object version) throws CacheException {
return null;
}
@Override
public void unlockItem(SessionImplementor session, Object key, SoftLock lock) throws CacheException {
evict(key);
}
@Override
public EntityRegion getRegion() {
return (EntityRegion) region;
}
@Override
public boolean insert(SessionImplementor session, Object key, Object value, Object version) throws CacheException {
return false;
}
@Override
public boolean afterInsert(SessionImplementor session, Object key, Object value, Object version) throws CacheException {
region.put(session, key, value);
return true;
}
@Override
public boolean update(SessionImplementor session, Object key, Object value, Object currentVersion, Object previousVersion)
throws CacheException {
throw new UnsupportedOperationException("Unable to update read-only object");
}
@Override
public boolean afterUpdate(SessionImplementor session, Object key, Object value, Object currentVersion, Object previousVersion, SoftLock lock)
throws CacheException {
throw new UnsupportedOperationException("Unable to update read-only object");
}
@Override
public Object generateCacheKey(Object id, EntityPersister persister, SessionFactoryImplementor factory, String tenantIdentifier) {
return DefaultCacheKeysFactory.staticCreateEntityKey( id, persister, factory, tenantIdentifier );
}
@Override
public Object getCacheKeyId(Object cacheKey) {
return DefaultCacheKeysFactory.staticGetEntityId(cacheKey);
}
}

@ -1,101 +0,0 @@
/**
* Copyright (c) 2013-2019 Nikita Koksharov
*
* 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.
*/
package org.redisson.hibernate.strategy;
import org.hibernate.cache.CacheException;
import org.hibernate.cache.internal.DefaultCacheKeysFactory;
import org.hibernate.cache.spi.GeneralDataRegion;
import org.hibernate.cache.spi.NaturalIdRegion;
import org.hibernate.cache.spi.access.NaturalIdRegionAccessStrategy;
import org.hibernate.cache.spi.access.SoftLock;
import org.hibernate.cfg.Settings;
import org.hibernate.engine.spi.SessionImplementor;
import org.hibernate.persister.entity.EntityPersister;
/**
*
* @author Nikita Koksharov
*
*/
public class ReadOnlyNaturalIdRegionAccessStrategy extends BaseRegionAccessStrategy implements NaturalIdRegionAccessStrategy {
public ReadOnlyNaturalIdRegionAccessStrategy(Settings settings, GeneralDataRegion region) {
super(settings, region);
}
@Override
public Object get(SessionImplementor session, Object key, long txTimestamp) throws CacheException {
return region.get(session, key);
}
@Override
public boolean putFromLoad(SessionImplementor session, Object key, Object value, long txTimestamp, Object version, boolean minimalPutOverride)
throws CacheException {
if (minimalPutOverride && region.contains(key)) {
return false;
}
region.put(session, key, value);
return true;
}
@Override
public SoftLock lockItem(SessionImplementor session, Object key, Object version) throws CacheException {
return null;
}
@Override
public void unlockItem(SessionImplementor session, Object key, SoftLock lock) throws CacheException {
evict(key);
}
@Override
public NaturalIdRegion getRegion() {
return (NaturalIdRegion) region;
}
@Override
public boolean insert(SessionImplementor session, Object key, Object value) throws CacheException {
return false;
}
@Override
public boolean afterInsert(SessionImplementor session, Object key, Object value) throws CacheException {
region.put(session, key, value);
return true;
}
@Override
public boolean update(SessionImplementor session, Object key, Object value) throws CacheException {
throw new UnsupportedOperationException("Unable to update read-only object");
}
@Override
public boolean afterUpdate(SessionImplementor session, Object key, Object value, SoftLock lock) throws CacheException {
throw new UnsupportedOperationException("Unable to update read-only object");
}
@Override
public Object generateCacheKey(Object[] naturalIdValues, EntityPersister persister, SessionImplementor session) {
return DefaultCacheKeysFactory.staticCreateNaturalIdKey(naturalIdValues, persister, session);
}
@Override
public Object[] getNaturalIdValues(Object cacheKey) {
return DefaultCacheKeysFactory.staticGetNaturalIdValues(cacheKey);
}
}

@ -1,54 +0,0 @@
/**
* Copyright (c) 2013-2019 Nikita Koksharov
*
* 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.
*/
package org.redisson.hibernate.strategy;
import org.hibernate.cache.internal.DefaultCacheKeysFactory;
import org.hibernate.cache.spi.CollectionRegion;
import org.hibernate.cache.spi.GeneralDataRegion;
import org.hibernate.cache.spi.access.CollectionRegionAccessStrategy;
import org.hibernate.cfg.Settings;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.persister.collection.CollectionPersister;
import org.redisson.api.RMapCache;
/**
*
* @author Nikita Koksharov
*
*/
public class ReadWriteCollectionRegionAccessStrategy extends AbstractReadWriteAccessStrategy implements CollectionRegionAccessStrategy {
public ReadWriteCollectionRegionAccessStrategy(Settings settings, GeneralDataRegion region,
RMapCache<Object, Object> mapCache) {
super(settings, region, mapCache);
}
@Override
public CollectionRegion getRegion() {
return (CollectionRegion) region;
}
@Override
public Object generateCacheKey(Object id, CollectionPersister persister, SessionFactoryImplementor factory, String tenantIdentifier) {
return DefaultCacheKeysFactory.staticCreateCollectionKey( id, persister, factory, tenantIdentifier );
}
@Override
public Object getCacheKeyId(Object cacheKey) {
return DefaultCacheKeysFactory.staticGetCollectionId(cacheKey);
}
}

@ -1,135 +0,0 @@
/**
* Copyright (c) 2013-2019 Nikita Koksharov
*
* 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.
*/
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2010-2011, Red Hat Inc. or third-party contributors as
* indicated by the @author tags or express copyright attribution
* statements applied by the authors. All third-party contributions are
* distributed under license by Red Hat Inc.
*
* This copyrighted material is made available to anyone wishing to use, modify,
* copy, or redistribute it subject to the terms and conditions of the GNU
* Lesser General Public License, as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this distribution; if not, write to:
* Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
package org.redisson.hibernate.strategy;
import org.hibernate.cache.CacheException;
import org.hibernate.cache.internal.DefaultCacheKeysFactory;
import org.hibernate.cache.spi.EntityRegion;
import org.hibernate.cache.spi.GeneralDataRegion;
import org.hibernate.cache.spi.access.EntityRegionAccessStrategy;
import org.hibernate.cache.spi.access.SoftLock;
import org.hibernate.cfg.Settings;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.engine.spi.SessionImplementor;
import org.hibernate.persister.entity.EntityPersister;
import org.redisson.api.RLock;
import org.redisson.api.RMapCache;
/**
*
* @author Nikita Koksharov
* @author Strong Liu
*
*/
public class ReadWriteEntityRegionAccessStrategy extends AbstractReadWriteAccessStrategy implements EntityRegionAccessStrategy {
public ReadWriteEntityRegionAccessStrategy(Settings settings, GeneralDataRegion region, RMapCache<Object, Object> mapCache) {
super(settings, region, mapCache);
}
@Override
public EntityRegion getRegion() {
return (EntityRegion) region;
}
@Override
public boolean insert(SessionImplementor session, Object key, Object value, Object version) throws CacheException {
return false;
}
@Override
public boolean afterInsert(SessionImplementor session, Object key, Object value, Object version) throws CacheException {
RLock writeLock = mapCache.getReadWriteLock(key).writeLock();
writeLock.lock();
try {
Lockable item = (Lockable) region.get(session, key);
if (item == null) {
region.put(session, key, new Item(value, version, region.nextTimestamp()));
return true;
} else {
return false;
}
} finally {
writeLock.unlock();
}
}
@Override
public boolean update(SessionImplementor session, Object key, Object value, Object currentVersion, Object previousVersion)
throws CacheException {
return false;
}
@Override
public boolean afterUpdate(SessionImplementor session, Object key, Object value, Object currentVersion, Object previousVersion, SoftLock lock)
throws CacheException {
RLock writeLock = mapCache.getReadWriteLock(key).writeLock();
writeLock.lock();
try {
Lockable item = (Lockable) region.get(session, key);
if (item != null && item.isUnlockable(lock)) {
Lock lockItem = (Lock) item;
if (lockItem.wasLockedConcurrently()) {
decrementLock(session, key, lockItem );
return false;
} else {
region.put(session, key, new Item(value, currentVersion, region.nextTimestamp()));
return true;
}
} else {
handleLockExpiry(session, key, item );
return false;
}
} finally {
writeLock.unlock();
}
}
@Override
public Object generateCacheKey(Object id, EntityPersister persister, SessionFactoryImplementor factory, String tenantIdentifier) {
return DefaultCacheKeysFactory.staticCreateEntityKey(id, persister, factory, tenantIdentifier);
}
@Override
public Object getCacheKeyId(Object cacheKey) {
return DefaultCacheKeysFactory.staticGetEntityId(cacheKey);
}
}

@ -1,133 +0,0 @@
/**
* Copyright (c) 2013-2019 Nikita Koksharov
*
* 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.
*/
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2010-2011, Red Hat Inc. or third-party contributors as
* indicated by the @author tags or express copyright attribution
* statements applied by the authors. All third-party contributions are
* distributed under license by Red Hat Inc.
*
* This copyrighted material is made available to anyone wishing to use, modify,
* copy, or redistribute it subject to the terms and conditions of the GNU
* Lesser General Public License, as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this distribution; if not, write to:
* Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
package org.redisson.hibernate.strategy;
import org.hibernate.cache.CacheException;
import org.hibernate.cache.internal.DefaultCacheKeysFactory;
import org.hibernate.cache.spi.GeneralDataRegion;
import org.hibernate.cache.spi.NaturalIdRegion;
import org.hibernate.cache.spi.access.NaturalIdRegionAccessStrategy;
import org.hibernate.cache.spi.access.SoftLock;
import org.hibernate.cfg.Settings;
import org.hibernate.engine.spi.SessionImplementor;
import org.hibernate.persister.entity.EntityPersister;
import org.redisson.api.RLock;
import org.redisson.api.RMapCache;
/**
*
* @author Nikita Koksharov
* @author Eric Dalquist
*
*/
public class ReadWriteNaturalIdRegionAccessStrategy extends AbstractReadWriteAccessStrategy implements NaturalIdRegionAccessStrategy {
public ReadWriteNaturalIdRegionAccessStrategy(Settings settings, GeneralDataRegion region,
RMapCache<Object, Object> mapCache) {
super(settings, region, mapCache);
}
@Override
public NaturalIdRegion getRegion() {
return (NaturalIdRegion) region;
}
@Override
public boolean insert(SessionImplementor session, Object key, Object value) throws CacheException {
return false;
}
@Override
public boolean afterInsert(SessionImplementor session, Object key, Object value) throws CacheException {
RLock writeLock = mapCache.getReadWriteLock(key).writeLock();
writeLock.lock();
try {
Lockable item = (Lockable) region.get(session, key);
if (item == null) {
region.put(session, key, new Item(value, null, region.nextTimestamp()));
return true;
} else {
return false;
}
} finally {
writeLock.unlock();
}
}
@Override
public boolean update(SessionImplementor session, Object key, Object value) throws CacheException {
return false;
}
@Override
public boolean afterUpdate(SessionImplementor session, Object key, Object value, SoftLock lock) throws CacheException {
RLock writeLock = mapCache.getReadWriteLock(key).writeLock();
writeLock.lock();
try {
Lockable item = (Lockable) region.get(session, key);
if (item != null && item.isUnlockable(lock)) {
Lock lockItem = (Lock) item;
if (lockItem.wasLockedConcurrently()) {
decrementLock(session, key, lockItem);
return false;
} else {
region.put(session, key, new Item(value, null, region.nextTimestamp()));
return true;
}
} else {
handleLockExpiry(session, key, item);
return false;
}
} finally {
writeLock.unlock();
}
}
@Override
public Object generateCacheKey(Object[] naturalIdValues, EntityPersister persister, SessionImplementor session) {
return DefaultCacheKeysFactory.staticCreateNaturalIdKey(naturalIdValues, persister, session);
}
@Override
public Object[] getNaturalIdValues(Object cacheKey) {
return DefaultCacheKeysFactory.staticGetNaturalIdValues(cacheKey);
}
}

@ -1,85 +0,0 @@
/**
* Copyright (c) 2013-2019 Nikita Koksharov
*
* 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.
*/
package org.redisson.hibernate.strategy;
import org.hibernate.cache.CacheException;
import org.hibernate.cache.internal.DefaultCacheKeysFactory;
import org.hibernate.cache.spi.CollectionRegion;
import org.hibernate.cache.spi.GeneralDataRegion;
import org.hibernate.cache.spi.access.CollectionRegionAccessStrategy;
import org.hibernate.cache.spi.access.SoftLock;
import org.hibernate.cfg.Settings;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.engine.spi.SessionImplementor;
import org.hibernate.persister.collection.CollectionPersister;
/**
*
* @author Nikita Koksharov
*
*/
public class TransactionalCollectionRegionAccessStrategy extends BaseRegionAccessStrategy implements CollectionRegionAccessStrategy {
public TransactionalCollectionRegionAccessStrategy(Settings settings, GeneralDataRegion region) {
super(settings, region);
}
@Override
public CollectionRegion getRegion() {
return (CollectionRegion) region;
}
@Override
public Object get(SessionImplementor session, Object key, long txTimestamp) throws CacheException {
return region.get(session, key);
}
@Override
public boolean putFromLoad(SessionImplementor session, Object key, Object value, long txTimestamp, Object version, boolean minimalPutOverride)
throws CacheException {
if (minimalPutOverride && region.contains(key)) {
return false;
}
region.put(session, key, value);
return true;
}
@Override
public SoftLock lockItem(SessionImplementor session, Object key, Object version) throws CacheException {
return null;
}
@Override
public void unlockItem(SessionImplementor session, Object key, SoftLock lock) throws CacheException {
}
@Override
public void remove(SessionImplementor session, Object key) throws CacheException {
region.evict(key);
}
@Override
public Object generateCacheKey(Object id, CollectionPersister persister, SessionFactoryImplementor factory, String tenantIdentifier) {
return DefaultCacheKeysFactory.staticCreateCollectionKey( id, persister, factory, tenantIdentifier );
}
@Override
public Object getCacheKeyId(Object cacheKey) {
return DefaultCacheKeysFactory.staticGetCollectionId(cacheKey);
}
}

@ -1,108 +0,0 @@
/**
* Copyright (c) 2013-2019 Nikita Koksharov
*
* 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.
*/
package org.redisson.hibernate.strategy;
import org.hibernate.cache.CacheException;
import org.hibernate.cache.internal.DefaultCacheKeysFactory;
import org.hibernate.cache.spi.EntityRegion;
import org.hibernate.cache.spi.GeneralDataRegion;
import org.hibernate.cache.spi.access.EntityRegionAccessStrategy;
import org.hibernate.cache.spi.access.SoftLock;
import org.hibernate.cfg.Settings;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.engine.spi.SessionImplementor;
import org.hibernate.persister.entity.EntityPersister;
/**
*
* @author Nikita Koksharov
*
*/
public class TransactionalEntityRegionAccessStrategy extends BaseRegionAccessStrategy implements EntityRegionAccessStrategy {
public TransactionalEntityRegionAccessStrategy(Settings settings, GeneralDataRegion region) {
super(settings, region);
}
@Override
public Object get(SessionImplementor session, Object key, long txTimestamp) throws CacheException {
return region.get(session, key);
}
@Override
public boolean putFromLoad(SessionImplementor session, Object key, Object value, long txTimestamp, Object version, boolean minimalPutOverride)
throws CacheException {
if (minimalPutOverride && region.contains(key)) {
return false;
}
region.put(session, key, value);
return true;
}
@Override
public SoftLock lockItem(SessionImplementor session, Object key, Object version) throws CacheException {
return null;
}
@Override
public void unlockItem(SessionImplementor session, Object key, SoftLock lock) throws CacheException {
}
@Override
public EntityRegion getRegion() {
return (EntityRegion) region;
}
@Override
public boolean insert(SessionImplementor session, Object key, Object value, Object version) throws CacheException {
region.put(session, key, value);
return true;
}
@Override
public boolean afterInsert(SessionImplementor session, Object key, Object value, Object version) throws CacheException {
return false;
}
@Override
public void remove(SessionImplementor session, Object key) throws CacheException {
region.evict(key);
}
@Override
public boolean update(SessionImplementor session, Object key, Object value, Object currentVersion, Object previousVersion)
throws CacheException {
return insert(session, key, value, currentVersion);
}
@Override
public boolean afterUpdate(SessionImplementor session, Object key, Object value, Object currentVersion, Object previousVersion, SoftLock lock)
throws CacheException {
return false;
}
@Override
public Object generateCacheKey(Object id, EntityPersister persister, SessionFactoryImplementor factory, String tenantIdentifier) {
return DefaultCacheKeysFactory.staticCreateEntityKey(id, persister, factory, tenantIdentifier);
}
@Override
public Object getCacheKeyId(Object cacheKey) {
return DefaultCacheKeysFactory.staticGetEntityId(cacheKey);
}
}

@ -1,105 +0,0 @@
/**
* Copyright (c) 2013-2019 Nikita Koksharov
*
* 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.
*/
package org.redisson.hibernate.strategy;
import org.hibernate.cache.CacheException;
import org.hibernate.cache.internal.DefaultCacheKeysFactory;
import org.hibernate.cache.spi.GeneralDataRegion;
import org.hibernate.cache.spi.NaturalIdRegion;
import org.hibernate.cache.spi.access.NaturalIdRegionAccessStrategy;
import org.hibernate.cache.spi.access.SoftLock;
import org.hibernate.cfg.Settings;
import org.hibernate.engine.spi.SessionImplementor;
import org.hibernate.persister.entity.EntityPersister;
/**
*
* @author Nikita Koksharov
*
*/
public class TransactionalNaturalIdRegionAccessStrategy extends BaseRegionAccessStrategy implements NaturalIdRegionAccessStrategy {
public TransactionalNaturalIdRegionAccessStrategy(Settings settings, GeneralDataRegion region) {
super(settings, region);
}
@Override
public Object get(SessionImplementor session, Object key, long txTimestamp) throws CacheException {
return region.get(session, key);
}
@Override
public boolean putFromLoad(SessionImplementor session, Object key, Object value, long txTimestamp, Object version, boolean minimalPutOverride)
throws CacheException {
if (minimalPutOverride && region.contains(key)) {
return false;
}
region.put(session, key, value);
return true;
}
@Override
public SoftLock lockItem(SessionImplementor session, Object key, Object version) throws CacheException {
return null;
}
@Override
public void unlockItem(SessionImplementor session, Object key, SoftLock lock) throws CacheException {
}
@Override
public NaturalIdRegion getRegion() {
return (NaturalIdRegion) region;
}
@Override
public void remove(SessionImplementor session, Object key) throws CacheException {
region.evict(key);
}
@Override
public boolean insert(SessionImplementor session, Object key, Object value) throws CacheException {
region.put(session, key, value);
return true;
}
@Override
public boolean afterInsert(SessionImplementor session, Object key, Object value) throws CacheException {
return false;
}
@Override
public boolean update(SessionImplementor session, Object key, Object value) throws CacheException {
return insert(session, key, value);
}
@Override
public boolean afterUpdate(SessionImplementor session, Object key, Object value, SoftLock lock) throws CacheException {
return false;
}
@Override
public Object generateCacheKey(Object[] naturalIdValues, EntityPersister persister, SessionImplementor session) {
return DefaultCacheKeysFactory.staticCreateNaturalIdKey(naturalIdValues, persister, session);
}
@Override
public Object[] getNaturalIdValues(Object cacheKey) {
return DefaultCacheKeysFactory.staticGetNaturalIdValues(cacheKey);
}
}

@ -1,11 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<blueprint default-activation="eager"
xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<bean id="strategyRegistrationProvider" class="org.redisson.hibernate.RedissonStrategyRegistrationProvider"/>
<service ref="strategyRegistrationProvider" interface="org.hibernate.boot.registry.selector.StrategyRegistrationProvider"/>
</blueprint>

@ -1,84 +0,0 @@
package org.redisson.hibernate;
import java.util.ArrayList;
import java.util.List;
import javax.persistence.Column;
import javax.persistence.ElementCollection;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import org.hibernate.annotations.Cache;
import org.hibernate.annotations.CacheConcurrencyStrategy;
import org.hibernate.annotations.GenericGenerator;
import org.hibernate.annotations.NaturalId;
import org.hibernate.annotations.NaturalIdCache;
/**
*
* @author Nikita Koksharov
*
*/
@Entity
@NamedQueries(@NamedQuery(name = "testQuery", query = "from ItemReadWrite where name = :name"))
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE, region = "item")
@NaturalIdCache
public class ItemReadWrite {
@Id
@GeneratedValue(generator = "increment")
@GenericGenerator(name = "increment", strategy = "increment")
private Long id;
private String name;
@NaturalId
private String nid;
@ElementCollection
@JoinTable(name = "Entries", joinColumns = @JoinColumn(name="Item_id"))
@Column(name = "entry", nullable = false)
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE, region = "item_entries")
private List<String> entries = new ArrayList<String>();
public ItemReadWrite() {
}
public ItemReadWrite(String name) {
this.name = name;
}
public String getNid() {
return nid;
}
public void setNid(String nid) {
this.nid = nid;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<String> getEntries() {
return entries;
}
}

@ -1,84 +0,0 @@
package org.redisson.hibernate;
import java.util.ArrayList;
import java.util.List;
import javax.persistence.Column;
import javax.persistence.ElementCollection;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import org.hibernate.annotations.Cache;
import org.hibernate.annotations.CacheConcurrencyStrategy;
import org.hibernate.annotations.GenericGenerator;
import org.hibernate.annotations.NaturalId;
import org.hibernate.annotations.NaturalIdCache;
/**
*
* @author Nikita Koksharov
*
*/
@Entity
@NamedQueries(@NamedQuery(name = "testQuery", query = "from ItemTransactional where name = :name"))
@Cache(usage = CacheConcurrencyStrategy.TRANSACTIONAL, region = "item")
@NaturalIdCache
public class ItemTransactional {
@Id
@GeneratedValue(generator = "increment")
@GenericGenerator(name = "increment", strategy = "increment")
private Long id;
private String name;
@NaturalId
private String nid;
@ElementCollection
@JoinTable(name = "Entries", joinColumns = @JoinColumn(name="Item_id"))
@Column(name = "entry", nullable = false)
@Cache(usage = CacheConcurrencyStrategy.TRANSACTIONAL, region = "item_entries")
private List<String> entries = new ArrayList<String>();
public ItemTransactional() {
}
public ItemTransactional(String name) {
this.name = name;
}
public String getNid() {
return nid;
}
public void setNid(String nid) {
this.nid = nid;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<String> getEntries() {
return entries;
}
}

@ -1,232 +0,0 @@
package org.redisson.hibernate;
import static org.assertj.core.api.Assertions.assertThat;
import java.util.Arrays;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.cfg.Configuration;
import org.hibernate.cfg.Environment;
import org.hibernate.stat.Statistics;
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.redisson.hibernate.RedissonRegionFactory;
/**
*
* @author Nikita Koksharov
*
*/
public class ReadWriteTest extends BaseCoreFunctionalTestCase {
@Override
protected Class<?>[] getAnnotatedClasses() {
return new Class[] { ItemReadWrite.class};
}
@Override
protected void configure(Configuration cfg) {
super.configure(cfg);
cfg.setProperty(Environment.DRIVER, org.h2.Driver.class.getName());
cfg.setProperty(Environment.URL, "jdbc:h2:mem:db1;DB_CLOSE_DELAY=-1;MVCC=TRUE");
cfg.setProperty(Environment.USER, "sa");
cfg.setProperty(Environment.PASS, "");
cfg.setProperty(Environment.CACHE_REGION_PREFIX, "");
cfg.setProperty(Environment.GENERATE_STATISTICS, "true");
cfg.setProperty(Environment.USE_SECOND_LEVEL_CACHE, "true");
cfg.setProperty(Environment.USE_QUERY_CACHE, "true");
cfg.setProperty(Environment.CACHE_REGION_FACTORY, RedissonRegionFactory.class.getName());
cfg.setProperty("hibernate.cache.redisson.item.eviction.max_entries", "100");
cfg.setProperty("hibernate.cache.redisson.item.expiration.time_to_live", "1500");
cfg.setProperty("hibernate.cache.redisson.item.expiration.max_idle_time", "1000");
}
@Before
public void before() {
sessionFactory().getCache().evictEntityRegions();
sessionFactory().getStatistics().clear();
}
@Test
public void testTimeToLive() throws InterruptedException {
Statistics stats = sessionFactory().getStatistics();
Long id = null;
Session s = openSession();
s.beginTransaction();
ItemReadWrite item = new ItemReadWrite( "data" );
id = (Long) s.save( item );
s.flush();
s.getTransaction().commit();
s.close();
Thread.sleep(900);
s = openSession();
s.beginTransaction();
item = (ItemReadWrite) s.get(ItemReadWrite.class, id);
Assert.assertEquals("data", item.getName());
s.getTransaction().commit();
s.close();
Assert.assertEquals(1, stats.getSecondLevelCacheStatistics("item").getHitCount());
Assert.assertEquals(0, stats.getSecondLevelCacheStatistics("item").getMissCount());
Thread.sleep(600);
s = openSession();
s.beginTransaction();
item = (ItemReadWrite) s.get(ItemReadWrite.class, id);
Assert.assertEquals("data", item.getName());
s.delete(item);
s.getTransaction().commit();
s.close();
Assert.assertEquals(1, stats.getSecondLevelCacheStatistics("item").getHitCount());
Assert.assertEquals(1, stats.getSecondLevelCacheStatistics("item").getMissCount());
}
@Test
public void testQuery() {
Statistics stats = sessionFactory().getStatistics();
Session s = openSession();
s.beginTransaction();
ItemReadWrite item = new ItemReadWrite("data");
item.getEntries().addAll(Arrays.asList("a", "b", "c"));
s.save(item);
s.flush();
s.getTransaction().commit();
s = openSession();
s.beginTransaction();
Query query = s.getNamedQuery("testQuery");
query.setCacheable(true);
query.setCacheRegion("myTestQuery");
query.setParameter("name", "data");
item = (ItemReadWrite) query.uniqueResult();
s.getTransaction().commit();
s.close();
Assert.assertEquals(1, stats.getSecondLevelCacheStatistics("myTestQuery").getPutCount());
s = openSession();
s.beginTransaction();
Query query2 = s.getNamedQuery("testQuery");
query2.setCacheable(true);
query2.setCacheRegion("myTestQuery");
query2.setParameter("name", "data");
item = (ItemReadWrite) query2.uniqueResult();
s.delete(item);
s.getTransaction().commit();
s.close();
Assert.assertEquals(1, stats.getSecondLevelCacheStatistics("myTestQuery").getHitCount());
stats.logSummary();
}
@Test
public void testCollection() {
Long id = null;
Statistics stats = sessionFactory().getStatistics();
Session s = openSession();
s.beginTransaction();
ItemReadWrite item = new ItemReadWrite("data");
item.getEntries().addAll(Arrays.asList("a", "b", "c"));
id = (Long) s.save(item);
s.flush();
s.getTransaction().commit();
s = openSession();
s.beginTransaction();
item = (ItemReadWrite) s.get(ItemReadWrite.class, id);
assertThat(item.getEntries()).containsExactly("a", "b", "c");
s.getTransaction().commit();
s.close();
Assert.assertEquals(1, stats.getSecondLevelCacheStatistics("item_entries").getPutCount());
s = openSession();
s.beginTransaction();
item = (ItemReadWrite) s.get(ItemReadWrite.class, id);
assertThat(item.getEntries()).containsExactly("a", "b", "c");
s.delete(item);
s.getTransaction().commit();
s.close();
Assert.assertEquals(1, stats.getSecondLevelCacheStatistics("item_entries").getHitCount());
}
@Test
public void testNaturalId() {
Statistics stats = sessionFactory().getStatistics();
Session s = openSession();
s.beginTransaction();
ItemReadWrite item = new ItemReadWrite("data");
item.setNid("123");
s.save(item);
s.flush();
s.getTransaction().commit();
Assert.assertEquals(1, stats.getSecondLevelCacheStatistics("item").getPutCount());
Assert.assertEquals(1, stats.getNaturalIdCacheStatistics("item##NaturalId").getPutCount());
s = openSession();
s.beginTransaction();
item = (ItemReadWrite) s.bySimpleNaturalId(ItemReadWrite.class).load("123");
assertThat(item).isNotNull();
s.delete(item);
s.getTransaction().commit();
s.close();
Assert.assertEquals(1, stats.getSecondLevelCacheStatistics("item").getHitCount());
Assert.assertEquals(1, stats.getNaturalIdCacheStatistics("item##NaturalId").getHitCount());
sessionFactory().getStatistics().logSummary();
}
@Test
public void testUpdateWithRefreshThenRollback() {
Statistics stats = sessionFactory().getStatistics();
Long id = null;
Session s = openSession();
s.beginTransaction();
ItemReadWrite item = new ItemReadWrite( "data" );
id = (Long) s.save( item );
s.flush();
s.getTransaction().commit();
Assert.assertEquals(1, stats.getSecondLevelCacheStatistics("item").getPutCount());
s = openSession();
s.beginTransaction();
item = (ItemReadWrite) s.get(ItemReadWrite.class, id);
item.setName("newdata");
s.update(item);
s.flush();
s.refresh(item);
s.getTransaction().rollback();
s.clear();
s.close();
s = openSession();
s.beginTransaction();
item = (ItemReadWrite) s.get(ItemReadWrite.class, id);
Assert.assertEquals("data", item.getName());
s.delete(item);
s.getTransaction().commit();
s.close();
Assert.assertEquals(1, stats.getSecondLevelCacheStatistics("item").getHitCount());
}
}

@ -1,181 +0,0 @@
package org.redisson.hibernate;
import static org.assertj.core.api.Assertions.assertThat;
import java.util.Arrays;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.cfg.Configuration;
import org.hibernate.cfg.Environment;
import org.hibernate.stat.Statistics;
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.redisson.hibernate.RedissonRegionFactory;
/**
*
* @author Nikita Koksharov
*
*/
public class TransactionalTest extends BaseCoreFunctionalTestCase {
@Override
protected Class<?>[] getAnnotatedClasses() {
return new Class[] { ItemTransactional.class};
}
@Override
protected void configure(Configuration cfg) {
super.configure(cfg);
cfg.setProperty(Environment.DRIVER, org.h2.Driver.class.getName());
cfg.setProperty(Environment.URL, "jdbc:h2:mem:db1;DB_CLOSE_DELAY=-1;MVCC=TRUE");
cfg.setProperty(Environment.USER, "sa");
cfg.setProperty(Environment.PASS, "");
cfg.setProperty(Environment.CACHE_REGION_PREFIX, "");
cfg.setProperty(Environment.GENERATE_STATISTICS, "true");
cfg.setProperty(Environment.USE_SECOND_LEVEL_CACHE, "true");
cfg.setProperty(Environment.USE_QUERY_CACHE, "true");
cfg.setProperty(Environment.CACHE_REGION_FACTORY, RedissonRegionFactory.class.getName());
}
@Before
public void before() {
sessionFactory().getCache().evictEntityRegions();
sessionFactory().getStatistics().clear();
}
@Test
public void testQuery() {
Statistics stats = sessionFactory().getStatistics();
Session s = openSession();
s.beginTransaction();
ItemTransactional item = new ItemTransactional("data");
item.getEntries().addAll(Arrays.asList("a", "b", "c"));
s.save(item);
s.flush();
s.getTransaction().commit();
s = openSession();
s.beginTransaction();
Query query = s.getNamedQuery("testQuery");
query.setCacheable(true);
query.setCacheRegion("myTestQuery");
query.setParameter("name", "data");
item = (ItemTransactional) query.uniqueResult();
s.getTransaction().commit();
s.close();
Assert.assertEquals(1, stats.getSecondLevelCacheStatistics("myTestQuery").getPutCount());
s = openSession();
s.beginTransaction();
Query query2 = s.getNamedQuery("testQuery");
query2.setCacheable(true);
query2.setCacheRegion("myTestQuery");
query2.setParameter("name", "data");
item = (ItemTransactional) query2.uniqueResult();
s.delete(item);
s.getTransaction().commit();
s.close();
Assert.assertEquals(1, stats.getSecondLevelCacheStatistics("myTestQuery").getHitCount());
stats.logSummary();
}
@Test
public void testCollection() {
Long id = null;
Statistics stats = sessionFactory().getStatistics();
Session s = openSession();
s.beginTransaction();
ItemTransactional item = new ItemTransactional("data");
item.getEntries().addAll(Arrays.asList("a", "b", "c"));
id = (Long) s.save(item);
s.flush();
s.getTransaction().commit();
s = openSession();
s.beginTransaction();
item = (ItemTransactional) s.get(ItemTransactional.class, id);
assertThat(item.getEntries()).containsExactly("a", "b", "c");
s.getTransaction().commit();
s.close();
Assert.assertEquals(1, stats.getSecondLevelCacheStatistics("item_entries").getPutCount());
s = openSession();
s.beginTransaction();
item = (ItemTransactional) s.get(ItemTransactional.class, id);
assertThat(item.getEntries()).containsExactly("a", "b", "c");
s.delete(item);
s.getTransaction().commit();
s.close();
Assert.assertEquals(1, stats.getSecondLevelCacheStatistics("item_entries").getHitCount());
}
@Test
public void testNaturalId() {
Statistics stats = sessionFactory().getStatistics();
Session s = openSession();
s.beginTransaction();
ItemTransactional item = new ItemTransactional("data");
item.setNid("123");
s.save(item);
s.flush();
s.getTransaction().commit();
Assert.assertEquals(1, stats.getSecondLevelCacheStatistics("item").getPutCount());
Assert.assertEquals(1, stats.getNaturalIdCacheStatistics("item##NaturalId").getPutCount());
s = openSession();
s.beginTransaction();
item = (ItemTransactional) s.bySimpleNaturalId(ItemTransactional.class).load("123");
assertThat(item).isNotNull();
s.delete(item);
s.getTransaction().commit();
s.close();
Assert.assertEquals(1, stats.getSecondLevelCacheStatistics("item").getHitCount());
Assert.assertEquals(1, stats.getNaturalIdCacheStatistics("item##NaturalId").getHitCount());
sessionFactory().getStatistics().logSummary();
}
@Test
public void testUpdateWithRefreshThenRollback() {
Statistics stats = sessionFactory().getStatistics();
Long id = null;
Session s = openSession();
s.beginTransaction();
ItemTransactional item = new ItemTransactional( "data" );
id = (Long) s.save( item );
s.flush();
s.getTransaction().commit();
Assert.assertEquals(1, stats.getSecondLevelCacheStatistics("item").getPutCount());
s = openSession();
s.beginTransaction();
item = (ItemTransactional) s.get(ItemTransactional.class, id);
item.setName("newdata");
s.update(item);
s.flush();
s.refresh(item);
s.getTransaction().rollback();
s.clear();
s.close();
Assert.assertEquals(1, stats.getSecondLevelCacheStatistics("item").getHitCount());
}
}

@ -1,8 +0,0 @@
{
"singleServerConfig":{
"address": "redis://127.0.0.1:6379"
},
"codec":{
"class":"org.redisson.codec.FstCodec"
}
}

@ -1,8 +0,0 @@
{
"singleServerConfig":{
"address": "redis://127.0.0.1:6379"
},
"codec":{
"class":"org.redisson.codec.FstCodec"
}
}

@ -1,103 +0,0 @@
<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.redisson</groupId>
<artifactId>redisson-hibernate</artifactId>
<version>3.11.7-SNAPSHOT</version>
<relativePath>../</relativePath>
</parent>
<artifactId>redisson-hibernate-52</artifactId>
<packaging>jar</packaging>
<name>Redisson/Hibernate-5.2.x</name>
<dependencies>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>5.2.17.Final</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-testing</artifactId>
<version>5.2.17.Final</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.javassist</groupId>
<artifactId>javassist</artifactId>
<version>3.25.0-GA</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.3.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-impl</artifactId>
<version>2.3.1</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<version>3.1.2</version>
<configuration>
<archive>
<manifestEntries>
<Build-Time>${maven.build.timestamp}</Build-Time>
<Automatic-Module-Name>redisson.hibernate52</Automatic-Module-Name>
</manifestEntries>
</archive>
</configuration>
</plugin>
<plugin>
<groupId>com.mycila</groupId>
<artifactId>license-maven-plugin</artifactId>
<version>3.0</version>
<configuration>
<basedir>${basedir}</basedir>
<header>${basedir}/../../header.txt</header>
<quiet>false</quiet>
<failIfMissing>true</failIfMissing>
<aggregate>false</aggregate>
<includes>
<include>src/main/java/org/redisson/</include>
</includes>
<excludes>
<exclude>target/**</exclude>
</excludes>
<useDefaultExcludes>true</useDefaultExcludes>
<mapping>
<java>JAVADOC_STYLE</java>
</mapping>
<strictCheck>true</strictCheck>
<useDefaultMapping>true</useDefaultMapping>
<encoding>UTF-8</encoding>
</configuration>
<executions>
<execution>
<goals>
<goal>check</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

@ -1,71 +0,0 @@
/**
* Copyright (c) 2013-2019 Nikita Koksharov
*
* 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.
*/
package org.redisson.hibernate;
import java.util.Properties;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import org.hibernate.cache.CacheException;
import org.hibernate.engine.jndi.internal.JndiServiceImpl;
import org.hibernate.internal.util.config.ConfigurationHelper;
import org.hibernate.internal.util.jndi.JndiHelper;
import org.redisson.api.RedissonClient;
/**
* Hibernate Cache region factory based on Redisson.
* Uses Redisson instance located in JNDI.
*
* @author Nikita Koksharov
*
*/
public class JndiRedissonRegionFactory extends RedissonRegionFactory {
private static final long serialVersionUID = -4814502675083325567L;
public static final String JNDI_NAME = CONFIG_PREFIX + "jndi_name";
@Override
protected RedissonClient createRedissonClient(Properties properties) {
String jndiName = ConfigurationHelper.getString(JNDI_NAME, properties);
if (jndiName == null) {
throw new CacheException(JNDI_NAME + " property not set");
}
Properties jndiProperties = JndiServiceImpl.extractJndiProperties(properties);
InitialContext context = null;
try {
context = new InitialContext(jndiProperties);
return (RedissonClient) context.lookup(jndiName);
} catch (NamingException e) {
throw new CacheException("Unable to locate Redisson instance by name: " + jndiName, e);
} finally {
if (context != null) {
try {
context.close();
} catch (NamingException e) {
throw new CacheException("Unable to close JNDI context", e);
}
}
}
}
@Override
public void stop() {
}
}

@ -1,229 +0,0 @@
/**
* Copyright (c) 2013-2019 Nikita Koksharov
*
* 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.
*/
package org.redisson.hibernate;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;
import java.util.Properties;
import org.hibernate.boot.registry.selector.spi.StrategySelector;
import org.hibernate.boot.spi.SessionFactoryOptions;
import org.hibernate.cache.CacheException;
import org.hibernate.cache.internal.DefaultCacheKeysFactory;
import org.hibernate.cache.spi.CacheDataDescription;
import org.hibernate.cache.spi.CacheKeysFactory;
import org.hibernate.cache.spi.CollectionRegion;
import org.hibernate.cache.spi.EntityRegion;
import org.hibernate.cache.spi.NaturalIdRegion;
import org.hibernate.cache.spi.QueryResultsRegion;
import org.hibernate.cache.spi.RegionFactory;
import org.hibernate.cache.spi.TimestampsRegion;
import org.hibernate.cache.spi.access.AccessType;
import org.hibernate.cfg.Environment;
import org.hibernate.cfg.Settings;
import org.hibernate.internal.util.config.ConfigurationHelper;
import org.jboss.logging.Logger;
import org.redisson.Redisson;
import org.redisson.api.RMapCache;
import org.redisson.api.RScript;
import org.redisson.api.RedissonClient;
import org.redisson.client.codec.LongCodec;
import org.redisson.config.Config;
import org.redisson.hibernate.region.RedissonCollectionRegion;
import org.redisson.hibernate.region.RedissonEntityRegion;
import org.redisson.hibernate.region.RedissonNaturalIdRegion;
import org.redisson.hibernate.region.RedissonQueryRegion;
import org.redisson.hibernate.region.RedissonTimestampsRegion;
/**
* Hibernate Cache region factory based on Redisson.
* Creates own Redisson instance during region start.
*
* @author Nikita Koksharov
*
*/
public class RedissonRegionFactory implements RegionFactory {
private static final Logger log = Logger.getLogger( RedissonRegionFactory.class );
private static final long serialVersionUID = 3785315696581773811L;
public static final String QUERY_DEF = "query";
public static final String COLLECTION_DEF = "collection";
public static final String ENTITY_DEF = "entity";
public static final String NATURAL_ID_DEF = "naturalid";
public static final String TIMESTAMPS_DEF = "timestamps";
public static final String MAX_ENTRIES_SUFFIX = ".eviction.max_entries";
public static final String TTL_SUFFIX = ".expiration.time_to_live";
public static final String MAX_IDLE_SUFFIX = ".expiration.max_idle_time";
public static final String CONFIG_PREFIX = "hibernate.cache.redisson.";
public static final String REDISSON_CONFIG_PATH = CONFIG_PREFIX + "config";
protected RedissonClient redisson;
private Settings settings;
private CacheKeysFactory cacheKeysFactory;
@Override
public void start(SessionFactoryOptions settings, Properties properties) throws CacheException {
this.redisson = createRedissonClient(properties);
this.settings = new Settings(settings);
StrategySelector selector = settings.getServiceRegistry().getService(StrategySelector.class);
cacheKeysFactory = selector.resolveDefaultableStrategy(CacheKeysFactory.class,
properties.get(Environment.CACHE_KEYS_FACTORY), new DefaultCacheKeysFactory());
}
protected RedissonClient createRedissonClient(Properties properties) {
Config config = null;
if (!properties.containsKey(REDISSON_CONFIG_PATH)) {
config = loadConfig(RedissonRegionFactory.class.getClassLoader(), "redisson.json");
if (config == null) {
config = loadConfig(RedissonRegionFactory.class.getClassLoader(), "redisson.yaml");
}
} else {
String configPath = ConfigurationHelper.getString(REDISSON_CONFIG_PATH, properties);
config = loadConfig(RedissonRegionFactory.class.getClassLoader(), configPath);
if (config == null) {
config = loadConfig(configPath);
}
}
if (config == null) {
throw new CacheException("Unable to locate Redisson configuration");
}
return Redisson.create(config);
}
private Config loadConfig(String configPath) {
try {
return Config.fromJSON(new File(configPath));
} catch (IOException e) {
// trying next format
try {
return Config.fromYAML(new File(configPath));
} catch (IOException e1) {
throw new CacheException("Can't parse default yaml config", e1);
}
}
}
private Config loadConfig(ClassLoader classLoader, String fileName) {
InputStream is = classLoader.getResourceAsStream(fileName);
if (is != null) {
try {
return Config.fromJSON(is);
} catch (IOException e) {
try {
is = classLoader.getResourceAsStream(fileName);
return Config.fromYAML(is);
} catch (IOException e1) {
throw new CacheException("Can't parse yaml config", e1);
}
}
}
return null;
}
@Override
public void stop() {
redisson.shutdown();
}
@Override
public boolean isMinimalPutsEnabledByDefault() {
return true;
}
@Override
public AccessType getDefaultAccessType() {
return AccessType.TRANSACTIONAL;
}
@Override
public long nextTimestamp() {
long time = System.currentTimeMillis() << 12;
return redisson.getScript(LongCodec.INSTANCE).eval(RScript.Mode.READ_WRITE,
"local currentTime = redis.call('get', KEYS[1]);"
+ "if currentTime == false then "
+ "redis.call('set', KEYS[1], ARGV[1]); "
+ "return ARGV[1]; "
+ "end;"
+ "local nextValue = math.max(tonumber(ARGV[1]), tonumber(currentTime) + 1); "
+ "redis.call('set', KEYS[1], nextValue); "
+ "return nextValue;",
RScript.ReturnType.INTEGER, Arrays.<Object>asList("redisson-hibernate-timestamp"), time);
}
@Override
public EntityRegion buildEntityRegion(String regionName, Properties properties, CacheDataDescription metadata)
throws CacheException {
log.debug("Building entity cache region: " + regionName);
RMapCache<Object, Object> mapCache = getCache(regionName, properties, ENTITY_DEF);
return new RedissonEntityRegion(mapCache, this, metadata, settings, properties, ENTITY_DEF, cacheKeysFactory);
}
@Override
public NaturalIdRegion buildNaturalIdRegion(String regionName, Properties properties, CacheDataDescription metadata)
throws CacheException {
log.debug("Building naturalId cache region: " + regionName);
RMapCache<Object, Object> mapCache = getCache(regionName, properties, NATURAL_ID_DEF);
return new RedissonNaturalIdRegion(mapCache, this, metadata, settings, properties, NATURAL_ID_DEF, cacheKeysFactory);
}
@Override
public CollectionRegion buildCollectionRegion(String regionName, Properties properties,
CacheDataDescription metadata) throws CacheException {
log.debug("Building collection cache region: " + regionName);
RMapCache<Object, Object> mapCache = getCache(regionName, properties, COLLECTION_DEF);
return new RedissonCollectionRegion(mapCache, this, metadata, settings, properties, COLLECTION_DEF, cacheKeysFactory);
}
@Override
public QueryResultsRegion buildQueryResultsRegion(String regionName, Properties properties) throws CacheException {
log.debug("Building query cache region: " + regionName);
RMapCache<Object, Object> mapCache = getCache(regionName, properties, QUERY_DEF);
return new RedissonQueryRegion(mapCache, this, properties, QUERY_DEF);
}
@Override
public TimestampsRegion buildTimestampsRegion(String regionName, Properties properties) throws CacheException {
log.debug("Building timestamps cache region: " + regionName);
RMapCache<Object, Object> mapCache = getCache(regionName, properties, TIMESTAMPS_DEF);
return new RedissonTimestampsRegion(mapCache, this, properties, TIMESTAMPS_DEF);
}
protected RMapCache<Object, Object> getCache(String regionName, Properties properties, String defaultKey) {
return redisson.getMapCache(regionName);
}
}

@ -1,42 +0,0 @@
/**
* Copyright (c) 2013-2019 Nikita Koksharov
*
* 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.
*/
package org.redisson.hibernate;
import java.util.Collections;
import org.hibernate.boot.registry.selector.SimpleStrategyRegistrationImpl;
import org.hibernate.boot.registry.selector.StrategyRegistration;
import org.hibernate.boot.registry.selector.StrategyRegistrationProvider;
import org.hibernate.cache.spi.RegionFactory;
/**
*
* @author Nikita Koksharov
*
*/
public class RedissonStrategyRegistrationProvider implements StrategyRegistrationProvider {
@Override
public Iterable<StrategyRegistration> getStrategyRegistrations() {
return Collections.<StrategyRegistration>singleton(new SimpleStrategyRegistrationImpl(
RegionFactory.class,
RedissonRegionFactory.class,
"redisson",
RedissonRegionFactory.class.getName(),
RedissonRegionFactory.class.getSimpleName()));
}
}

@ -1,179 +0,0 @@
/**
* Copyright (c) 2013-2019 Nikita Koksharov
*
* 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.
*/
package org.redisson.hibernate.region;
import java.util.Collections;
import java.util.Map;
import java.util.Properties;
import java.util.concurrent.TimeUnit;
import org.hibernate.cache.CacheException;
import org.hibernate.cache.spi.CacheDataDescription;
import org.hibernate.cache.spi.GeneralDataRegion;
import org.hibernate.cache.spi.RegionFactory;
import org.hibernate.cache.spi.TransactionalDataRegion;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.redisson.api.RMapCache;
import org.redisson.hibernate.RedissonRegionFactory;
/**
*
* @author Nikita Koksharov
*
*/
public class BaseRegion implements TransactionalDataRegion, GeneralDataRegion {
final RMapCache<Object, Object> mapCache;
final RegionFactory regionFactory;
final CacheDataDescription metadata;
int ttl;
int maxIdle;
public BaseRegion(RMapCache<Object, Object> mapCache, RegionFactory regionFactory, CacheDataDescription metadata, Properties properties, String defaultKey) {
super();
this.mapCache = mapCache;
this.regionFactory = regionFactory;
this.metadata = metadata;
String maxEntries = getProperty(properties, mapCache.getName(), defaultKey, RedissonRegionFactory.MAX_ENTRIES_SUFFIX);
if (maxEntries != null) {
mapCache.setMaxSize(Integer.valueOf(maxEntries));
}
String timeToLive = getProperty(properties, mapCache.getName(), defaultKey, RedissonRegionFactory.TTL_SUFFIX);
if (timeToLive != null) {
ttl = Integer.valueOf(timeToLive);
}
String maxIdleTime = getProperty(properties, mapCache.getName(), defaultKey, RedissonRegionFactory.MAX_IDLE_SUFFIX);
if (maxIdleTime != null) {
maxIdle = Integer.valueOf(maxIdleTime);
}
}
private String getProperty(Properties properties, String name, String defaultKey, String suffix) {
String value = properties.getProperty(RedissonRegionFactory.CONFIG_PREFIX + name + suffix);
if (value != null) {
return value;
}
String defValue = properties.getProperty(RedissonRegionFactory.CONFIG_PREFIX + defaultKey + suffix);
if (defValue != null) {
return defValue;
}
return null;
}
@Override
public boolean isTransactionAware() {
// TODO Auto-generated method stub
return false;
}
@Override
public CacheDataDescription getCacheDataDescription() {
return metadata;
}
@Override
public String getName() {
return mapCache.getName();
}
@Override
public void destroy() throws CacheException {
try {
mapCache.destroy();
} catch (Exception e) {
throw new CacheException(e);
}
}
@Override
public boolean contains(Object key) {
try {
return mapCache.containsKey(key);
} catch (Exception e) {
throw new CacheException(e);
}
}
@Override
public long getSizeInMemory() {
return mapCache.sizeInMemory();
}
@Override
public long getElementCountInMemory() {
return mapCache.size();
}
@Override
public long getElementCountOnDisk() {
return -1;
}
@Override
public Map<?, ?> toMap() {
return Collections.unmodifiableMap(mapCache);
}
@Override
public long nextTimestamp() {
return regionFactory.nextTimestamp();
}
@Override
public int getTimeout() {
// 60 seconds (normalized value)
return (1 << 12) * 60000;
}
@Override
public Object get(SharedSessionContractImplementor session, Object key) throws CacheException {
try {
return mapCache.get(key);
} catch (Exception e) {
throw new CacheException(e);
}
}
@Override
public void put(SharedSessionContractImplementor session, Object key, Object value) throws CacheException {
try {
mapCache.fastPut(key, value, ttl, TimeUnit.MILLISECONDS, maxIdle, TimeUnit.MILLISECONDS);
} catch (Exception e) {
throw new CacheException(e);
}
}
@Override
public void evict(Object key) throws CacheException {
try {
mapCache.fastRemove(key);
} catch (Exception e) {
throw new CacheException(e);
}
}
@Override
public void evictAll() throws CacheException {
try {
mapCache.clear();
} catch (Exception e) {
throw new CacheException(e);
}
}
}

@ -1,73 +0,0 @@
/**
* Copyright (c) 2013-2019 Nikita Koksharov
*
* 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.
*/
package org.redisson.hibernate.region;
import java.util.Properties;
import org.hibernate.cache.CacheException;
import org.hibernate.cache.spi.CacheDataDescription;
import org.hibernate.cache.spi.CacheKeysFactory;
import org.hibernate.cache.spi.CollectionRegion;
import org.hibernate.cache.spi.RegionFactory;
import org.hibernate.cache.spi.access.AccessType;
import org.hibernate.cache.spi.access.CollectionRegionAccessStrategy;
import org.hibernate.cfg.Settings;
import org.redisson.api.RMapCache;
import org.redisson.hibernate.strategy.NonStrictReadWriteCollectionRegionAccessStrategy;
import org.redisson.hibernate.strategy.ReadOnlyCollectionRegionAccessStrategy;
import org.redisson.hibernate.strategy.ReadWriteCollectionRegionAccessStrategy;
import org.redisson.hibernate.strategy.TransactionalCollectionRegionAccessStrategy;
/**
*
* @author Nikita Koksharov
*
*/
public class RedissonCollectionRegion extends BaseRegion implements CollectionRegion {
private final Settings settings;
private final CacheKeysFactory cacheKeysFactory;
public RedissonCollectionRegion(RMapCache<Object, Object> mapCache, RegionFactory regionFactory,
CacheDataDescription metadata, Settings settings, Properties properties, String defaultKey, CacheKeysFactory cacheKeysFactory) {
super(mapCache, regionFactory, metadata, properties, defaultKey);
this.settings = settings;
this.cacheKeysFactory = cacheKeysFactory;
}
public CacheKeysFactory getCacheKeysFactory() {
return cacheKeysFactory;
}
@Override
public CollectionRegionAccessStrategy buildAccessStrategy(AccessType accessType) throws CacheException {
if (accessType == AccessType.READ_ONLY) {
return new ReadOnlyCollectionRegionAccessStrategy(settings, this);
}
if (accessType == AccessType.READ_WRITE) {
return new ReadWriteCollectionRegionAccessStrategy(settings, this, mapCache);
}
if (accessType == AccessType.NONSTRICT_READ_WRITE) {
return new NonStrictReadWriteCollectionRegionAccessStrategy(settings, this);
}
if (accessType == AccessType.TRANSACTIONAL) {
return new TransactionalCollectionRegionAccessStrategy(settings, this);
}
throw new CacheException("Unsupported access strategy: " + accessType);
}
}

@ -1,73 +0,0 @@
/**
* Copyright (c) 2013-2019 Nikita Koksharov
*
* 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.
*/
package org.redisson.hibernate.region;
import java.util.Properties;
import org.hibernate.cache.CacheException;
import org.hibernate.cache.spi.CacheDataDescription;
import org.hibernate.cache.spi.CacheKeysFactory;
import org.hibernate.cache.spi.EntityRegion;
import org.hibernate.cache.spi.RegionFactory;
import org.hibernate.cache.spi.access.AccessType;
import org.hibernate.cache.spi.access.EntityRegionAccessStrategy;
import org.hibernate.cfg.Settings;
import org.redisson.api.RMapCache;
import org.redisson.hibernate.strategy.NonStrictReadWriteEntityRegionAccessStrategy;
import org.redisson.hibernate.strategy.ReadOnlyEntityRegionAccessStrategy;
import org.redisson.hibernate.strategy.ReadWriteEntityRegionAccessStrategy;
import org.redisson.hibernate.strategy.TransactionalEntityRegionAccessStrategy;
/**
*
* @author Nikita Koksharov
*
*/
public class RedissonEntityRegion extends BaseRegion implements EntityRegion {
private final Settings settings;
private final CacheKeysFactory cacheKeysFactory;
public RedissonEntityRegion(RMapCache<Object, Object> mapCache, RegionFactory regionFactory,
CacheDataDescription metadata, Settings settings, Properties properties, String defaultKey, CacheKeysFactory cacheKeysFactory) {
super(mapCache, regionFactory, metadata, properties, defaultKey);
this.settings = settings;
this.cacheKeysFactory = cacheKeysFactory;
}
public CacheKeysFactory getCacheKeysFactory() {
return cacheKeysFactory;
}
@Override
public EntityRegionAccessStrategy buildAccessStrategy(AccessType accessType) throws CacheException {
if (accessType == AccessType.READ_ONLY) {
return new ReadOnlyEntityRegionAccessStrategy(settings, this);
}
if (accessType == AccessType.READ_WRITE) {
return new ReadWriteEntityRegionAccessStrategy(settings, this, mapCache);
}
if (accessType == AccessType.NONSTRICT_READ_WRITE) {
return new NonStrictReadWriteEntityRegionAccessStrategy(settings, this);
}
if (accessType == AccessType.TRANSACTIONAL) {
return new TransactionalEntityRegionAccessStrategy(settings, this);
}
throw new CacheException("Unsupported access strategy: " + accessType);
}
}

@ -1,73 +0,0 @@
/**
* Copyright (c) 2013-2019 Nikita Koksharov
*
* 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.
*/
package org.redisson.hibernate.region;
import java.util.Properties;
import org.hibernate.cache.CacheException;
import org.hibernate.cache.spi.CacheDataDescription;
import org.hibernate.cache.spi.CacheKeysFactory;
import org.hibernate.cache.spi.NaturalIdRegion;
import org.hibernate.cache.spi.RegionFactory;
import org.hibernate.cache.spi.access.AccessType;
import org.hibernate.cache.spi.access.NaturalIdRegionAccessStrategy;
import org.hibernate.cfg.Settings;
import org.redisson.api.RMapCache;
import org.redisson.hibernate.strategy.NonStrictReadWriteNaturalIdRegionAccessStrategy;
import org.redisson.hibernate.strategy.ReadOnlyNaturalIdRegionAccessStrategy;
import org.redisson.hibernate.strategy.ReadWriteNaturalIdRegionAccessStrategy;
import org.redisson.hibernate.strategy.TransactionalNaturalIdRegionAccessStrategy;
/**
*
* @author Nikita Koksharov
*
*/
public class RedissonNaturalIdRegion extends BaseRegion implements NaturalIdRegion {
private final Settings settings;
private final CacheKeysFactory cacheKeysFactory;
public RedissonNaturalIdRegion(RMapCache<Object, Object> mapCache, RegionFactory regionFactory,
CacheDataDescription metadata, Settings settings, Properties properties, String defaultKey, CacheKeysFactory cacheKeysFactory) {
super(mapCache, regionFactory, metadata, properties, defaultKey);
this.settings = settings;
this.cacheKeysFactory = cacheKeysFactory;
}
public CacheKeysFactory getCacheKeysFactory() {
return cacheKeysFactory;
}
@Override
public NaturalIdRegionAccessStrategy buildAccessStrategy(AccessType accessType) throws CacheException {
if (accessType == AccessType.READ_ONLY) {
return new ReadOnlyNaturalIdRegionAccessStrategy(settings, this);
}
if (accessType == AccessType.READ_WRITE) {
return new ReadWriteNaturalIdRegionAccessStrategy(settings, this, mapCache);
}
if (accessType == AccessType.NONSTRICT_READ_WRITE) {
return new NonStrictReadWriteNaturalIdRegionAccessStrategy(settings, this);
}
if (accessType == AccessType.TRANSACTIONAL) {
return new TransactionalNaturalIdRegionAccessStrategy(settings, this);
}
throw new CacheException("Unsupported access strategy: " + accessType);
}
}

@ -1,36 +0,0 @@
/**
* Copyright (c) 2013-2019 Nikita Koksharov
*
* 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.
*/
package org.redisson.hibernate.region;
import java.util.Properties;
import org.hibernate.cache.spi.QueryResultsRegion;
import org.hibernate.cache.spi.RegionFactory;
import org.redisson.api.RMapCache;
/**
*
* @author Nikita Koksharov
*
*/
public class RedissonQueryRegion extends BaseRegion implements QueryResultsRegion {
public RedissonQueryRegion(RMapCache<Object, Object> mapCache,
RegionFactory regionFactory, Properties properties, String defaultKey) {
super(mapCache, regionFactory, null, properties, defaultKey);
}
}

@ -1,36 +0,0 @@
/**
* Copyright (c) 2013-2019 Nikita Koksharov
*
* 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.
*/
package org.redisson.hibernate.region;
import java.util.Properties;
import org.hibernate.cache.spi.RegionFactory;
import org.hibernate.cache.spi.TimestampsRegion;
import org.redisson.api.RMapCache;
/**
*
* @author Nikita Koksharov
*
*/
public class RedissonTimestampsRegion extends BaseRegion implements TimestampsRegion {
public RedissonTimestampsRegion(RMapCache<Object, Object> mapCache,
RegionFactory regionFactory, Properties properties, String defaultKey) {
super(mapCache, regionFactory, null, properties, defaultKey);
}
}

@ -1,356 +0,0 @@
/**
* Copyright (c) 2013-2019 Nikita Koksharov
*
* 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.
*/
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2010-2011, Red Hat Inc. or third-party contributors as
* indicated by the @author tags or express copyright attribution
* statements applied by the authors. All third-party contributions are
* distributed under license by Red Hat Inc.
*
* This copyrighted material is made available to anyone wishing to use, modify,
* copy, or redistribute it subject to the terms and conditions of the GNU
* Lesser General Public License, as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this distribution; if not, write to:
* Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
package org.redisson.hibernate.strategy;
import java.io.Serializable;
import java.util.Comparator;
import java.util.UUID;
import java.util.concurrent.atomic.AtomicLong;
import org.hibernate.cache.CacheException;
import org.hibernate.cache.spi.GeneralDataRegion;
import org.hibernate.cache.spi.TransactionalDataRegion;
import org.hibernate.cache.spi.access.SoftLock;
import org.hibernate.cfg.Settings;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.redisson.api.RLock;
import org.redisson.api.RMapCache;
/**
*
* @author Nikita Koksharov
* @author Strong Liu
*
*/
public class AbstractReadWriteAccessStrategy extends BaseRegionAccessStrategy {
private final UUID uuid = UUID.randomUUID();
private final AtomicLong nextLockId = new AtomicLong();
final RMapCache<Object, Object> mapCache;
public AbstractReadWriteAccessStrategy(Settings settings, GeneralDataRegion region, RMapCache<Object, Object> mapCache) {
super(settings, region);
this.mapCache = mapCache;
}
@Override
public Object get(SharedSessionContractImplementor session, Object key, long txTimestamp) throws CacheException {
RLock readLock = mapCache.getReadWriteLock(key).readLock();
readLock.lock();
try {
Lockable item = (Lockable) region.get(session, key);
if (item != null && item.isReadable(txTimestamp)) {
return item.getValue();
} else {
return null;
}
} finally {
readLock.unlock();
}
}
@Override
public boolean putFromLoad(SharedSessionContractImplementor session, Object key, Object value, long txTimestamp, Object version, boolean minimalPutOverride)
throws CacheException {
RLock writeLock = mapCache.getReadWriteLock(key).writeLock();
writeLock.lock();
try {
Lockable item = (Lockable) region.get(session, key);
Comparator<Object> comparator = ((TransactionalDataRegion)region).getCacheDataDescription().getVersionComparator();
boolean writeable = item == null || item.isWriteable(txTimestamp, version, comparator);
if (writeable) {
region.put(session, key, new Item(value, version, region.nextTimestamp()));
return true;
}
return false;
} finally {
writeLock.unlock();
}
}
@Override
public SoftLock lockItem(SharedSessionContractImplementor session, Object key, Object version) throws CacheException {
RLock writeLock = mapCache.getReadWriteLock(key).writeLock();
writeLock.lock();
try {
Lockable item = (Lockable) region.get(session, key);
long timeout = region.nextTimestamp() + region.getTimeout();
Lock lock;
if (item == null) {
lock = new Lock(timeout, uuid, nextLockId.getAndIncrement(), version);
} else {
lock = item.lock(timeout, uuid, nextLockId.getAndIncrement());
}
region.put(session, key, lock);
return lock;
} finally {
writeLock.unlock();
}
}
@Override
public void unlockItem(SharedSessionContractImplementor session, Object key, SoftLock lock) throws CacheException {
RLock writeLock = mapCache.getReadWriteLock(key).writeLock();
writeLock.lock();
try {
Lockable item = (Lockable) region.get(session, key);
if (item != null && item.isUnlockable(lock)) {
decrementLock(session, key, (Lock)item);
} else {
handleLockExpiry(session, key, item);
}
} finally {
writeLock.unlock();
}
}
/**
* Unlock and re-put the given key, lock combination.
*/
protected void decrementLock(SharedSessionContractImplementor session, Object key, Lock lock) {
lock.unlock(region.nextTimestamp());
region.put(session, key, lock);
}
/**
* Handle the timeout of a previous lock mapped to this key
*/
protected void handleLockExpiry(SharedSessionContractImplementor session, Object key, Lockable lock) {
long ts = region.nextTimestamp() + region.getTimeout();
// create new lock that times out immediately
Lock newLock = new Lock(ts, uuid, nextLockId.getAndIncrement(), null);
newLock.unlock(ts);
region.put(session, key, newLock);
}
/**
* Interface type implemented by all wrapper objects in the cache.
*/
public interface Lockable {
/**
* Returns <code>true</code> if the enclosed value can be read by a transaction started at the given time.
*/
public boolean isReadable(long txTimestamp);
/**
* Returns <code>true</code> if the enclosed value can be replaced with one of the given version by a
* transaction started at the given time.
*/
public boolean isWriteable(long txTimestamp, Object version, Comparator<Object> versionComparator);
/**
* Returns the enclosed value.
*/
public Object getValue();
/**
* Returns <code>true</code> if the given lock can be unlocked using the given SoftLock instance as a handle.
*/
public boolean isUnlockable(SoftLock lock);
/**
* Locks this entry, stamping it with the UUID and lockId given, with the lock timeout occuring at the specified
* time. The returned Lock object can be used to unlock the entry in the future.
*/
public Lock lock(long timeout, UUID uuid, long lockId);
}
/**
* Wrapper type representing unlocked items.
*/
public final static class Item implements Serializable, Lockable {
private static final long serialVersionUID = 1L;
private Object value;
private Object version;
private long timestamp;
/**
* Creates an unlocked item wrapping the given value with a version and creation timestamp.
*/
public Item(Object value, Object version, long timestamp) {
this.value = value;
this.version = version;
this.timestamp = timestamp;
}
@Override
public boolean isReadable(long txTimestamp) {
return txTimestamp > timestamp;
}
@Override
public boolean isWriteable(long txTimestamp, Object newVersion, Comparator<Object> versionComparator) {
return version != null && versionComparator.compare( version, newVersion ) < 0;
}
@Override
public Object getValue() {
return value;
}
@Override
public boolean isUnlockable(SoftLock lock) {
return false;
}
@Override
public Lock lock(long timeout, UUID uuid, long lockId) {
return new Lock(timeout, uuid, lockId, version);
}
}
/**
* Wrapper type representing locked items.
*/
public final static class Lock implements Serializable, Lockable, SoftLock {
private static final long serialVersionUID = 2L;
private UUID sourceUuid;
private long lockId;
private Object version;
private long timeout;
private boolean concurrent;
private int multiplicity = 1;
private long unlockTimestamp;
/**
* Creates a locked item with the given identifiers and object version.
*/
public Lock(long timeout, UUID sourceUuid, long lockId, Object version) {
this.timeout = timeout;
this.lockId = lockId;
this.version = version;
this.sourceUuid = sourceUuid;
}
@Override
public boolean isReadable(long txTimestamp) {
return false;
}
@Override
public boolean isWriteable(long txTimestamp, Object newVersion, Comparator versionComparator) {
if ( txTimestamp > timeout ) {
// if timedout then allow write
return true;
}
if ( multiplicity > 0 ) {
// if still locked then disallow write
return false;
}
return version == null ? txTimestamp > unlockTimestamp : versionComparator.compare(
version,
newVersion
) < 0;
}
@Override
public Object getValue() {
return null;
}
@Override
public boolean isUnlockable(SoftLock lock) {
return equals( lock );
}
@Override
public boolean equals(Object o) {
if ( o == this ) {
return true;
}
else if ( o instanceof Lock ) {
return ( lockId == ( (Lock) o ).lockId ) && sourceUuid.equals( ( (Lock) o ).sourceUuid );
}
else {
return false;
}
}
@Override
public int hashCode() {
int hash = ( sourceUuid != null ? sourceUuid.hashCode() : 0 );
int temp = (int) lockId;
for ( int i = 1; i < Long.SIZE / Integer.SIZE; i++ ) {
temp ^= ( lockId >>> ( i * Integer.SIZE ) );
}
return hash + temp;
}
/**
* Returns true if this Lock has been concurrently locked by more than one transaction.
*/
public boolean wasLockedConcurrently() {
return concurrent;
}
@Override
public Lock lock(long timeout, UUID uuid, long lockId) {
concurrent = true;
multiplicity++;
this.timeout = timeout;
return this;
}
/**
* Unlocks this Lock, and timestamps the unlock event.
*/
public void unlock(long timestamp) {
if ( --multiplicity == 0 ) {
unlockTimestamp = timestamp;
}
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder( "Lock Source-UUID:" + sourceUuid + " Lock-ID:" + lockId );
return sb.toString();
}
}
}

@ -1,74 +0,0 @@
/**
* Copyright (c) 2013-2019 Nikita Koksharov
*
* 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.
*/
package org.redisson.hibernate.strategy;
import org.hibernate.cache.CacheException;
import org.hibernate.cache.spi.GeneralDataRegion;
import org.hibernate.cache.spi.access.RegionAccessStrategy;
import org.hibernate.cache.spi.access.SoftLock;
import org.hibernate.cfg.Settings;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
/**
*
* @author Nikita Koksharov
*
*/
abstract class BaseRegionAccessStrategy implements RegionAccessStrategy {
final GeneralDataRegion region;
final Settings settings;
BaseRegionAccessStrategy(Settings settings, GeneralDataRegion region) {
this.settings = settings;
this.region = region;
}
@Override
public boolean putFromLoad(SharedSessionContractImplementor session, Object key, Object value, long txTimestamp, Object version) throws CacheException {
return putFromLoad(session, key, value, txTimestamp, version, settings.isMinimalPutsEnabled() );
}
@Override
public SoftLock lockRegion() throws CacheException {
return null;
}
@Override
public void unlockRegion(SoftLock lock) throws CacheException {
region.evictAll();
}
@Override
public void remove(SharedSessionContractImplementor session, Object key) throws CacheException {
}
@Override
public void removeAll() throws CacheException {
region.evictAll();
}
@Override
public void evict(Object key) throws CacheException {
region.evict(key);
}
@Override
public void evictAll() throws CacheException {
region.evictAll();
}
}

@ -1,87 +0,0 @@
/**
* Copyright (c) 2013-2019 Nikita Koksharov
*
* 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.
*/
package org.redisson.hibernate.strategy;
import org.hibernate.cache.CacheException;
import org.hibernate.cache.spi.CollectionRegion;
import org.hibernate.cache.spi.GeneralDataRegion;
import org.hibernate.cache.spi.access.CollectionRegionAccessStrategy;
import org.hibernate.cache.spi.access.SoftLock;
import org.hibernate.cfg.Settings;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.persister.collection.CollectionPersister;
import org.redisson.hibernate.region.RedissonCollectionRegion;
/**
*
* @author Nikita Koksharov
*
*/
public class NonStrictReadWriteCollectionRegionAccessStrategy extends BaseRegionAccessStrategy implements CollectionRegionAccessStrategy {
public NonStrictReadWriteCollectionRegionAccessStrategy(Settings settings, GeneralDataRegion region) {
super(settings, region);
}
@Override
public CollectionRegion getRegion() {
return (CollectionRegion) region;
}
@Override
public Object get(SharedSessionContractImplementor session, Object key, long txTimestamp) throws CacheException {
return region.get(session, key);
}
@Override
public boolean putFromLoad(SharedSessionContractImplementor session, Object key, Object value, long txTimestamp, Object version, boolean minimalPutOverride)
throws CacheException {
if (minimalPutOverride && region.contains(key)) {
return false;
}
region.put(session, key, value);
return true;
}
@Override
public SoftLock lockItem(SharedSessionContractImplementor session, Object key, Object version) throws CacheException {
return null;
}
@Override
public void unlockItem(SharedSessionContractImplementor session, Object key, SoftLock lock) throws CacheException {
evict(key);
}
@Override
public void remove(SharedSessionContractImplementor session, Object key) throws CacheException {
evict(key);
}
@Override
public Object generateCacheKey(Object id, CollectionPersister persister, SessionFactoryImplementor factory,
String tenantIdentifier) {
return ((RedissonCollectionRegion)region).getCacheKeysFactory().createCollectionKey( id, persister, factory, tenantIdentifier );
}
@Override
public Object getCacheKeyId(Object cacheKey) {
return ((RedissonCollectionRegion)region).getCacheKeysFactory().getCollectionId( cacheKey );
}
}

@ -1,110 +0,0 @@
/**
* Copyright (c) 2013-2019 Nikita Koksharov
*
* 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.
*/
package org.redisson.hibernate.strategy;
import org.hibernate.cache.CacheException;
import org.hibernate.cache.spi.EntityRegion;
import org.hibernate.cache.spi.GeneralDataRegion;
import org.hibernate.cache.spi.access.EntityRegionAccessStrategy;
import org.hibernate.cache.spi.access.SoftLock;
import org.hibernate.cfg.Settings;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.persister.entity.EntityPersister;
import org.redisson.hibernate.region.RedissonEntityRegion;
/**
*
* @author Nikita Koksharov
*
*/
public class NonStrictReadWriteEntityRegionAccessStrategy extends BaseRegionAccessStrategy implements EntityRegionAccessStrategy {
public NonStrictReadWriteEntityRegionAccessStrategy(Settings settings, GeneralDataRegion region) {
super(settings, region);
}
@Override
public Object get(SharedSessionContractImplementor session, Object key, long txTimestamp) throws CacheException {
return region.get(session, key);
}
@Override
public boolean putFromLoad(SharedSessionContractImplementor session, Object key, Object value, long txTimestamp, Object version, boolean minimalPutOverride)
throws CacheException {
if (minimalPutOverride && region.contains(key)) {
return false;
}
region.put(session, key, value);
return true;
}
@Override
public SoftLock lockItem(SharedSessionContractImplementor session, Object key, Object version) throws CacheException {
return null;
}
@Override
public void unlockItem(SharedSessionContractImplementor session, Object key, SoftLock lock) throws CacheException {
evict(key);
}
@Override
public EntityRegion getRegion() {
return (EntityRegion) region;
}
@Override
public boolean insert(SharedSessionContractImplementor session, Object key, Object value, Object version) throws CacheException {
return false;
}
@Override
public boolean afterInsert(SharedSessionContractImplementor session, Object key, Object value, Object version) throws CacheException {
return false;
}
@Override
public boolean update(SharedSessionContractImplementor session, Object key, Object value, Object currentVersion, Object previousVersion)
throws CacheException {
remove(session, key);
return false;
}
@Override
public boolean afterUpdate(SharedSessionContractImplementor session, Object key, Object value, Object currentVersion, Object previousVersion, SoftLock lock)
throws CacheException {
unlockItem(session, key, lock);
return false;
}
@Override
public void remove(SharedSessionContractImplementor session, Object key) throws CacheException {
evict(key);
}
@Override
public Object generateCacheKey(Object id, EntityPersister persister, SessionFactoryImplementor factory, String tenantIdentifier) {
return ((RedissonEntityRegion)region).getCacheKeysFactory().createEntityKey( id, persister, factory, tenantIdentifier );
}
@Override
public Object getCacheKeyId(Object cacheKey) {
return ((RedissonEntityRegion)region).getCacheKeysFactory().getEntityId( cacheKey );
}
}

@ -1,107 +0,0 @@
/**
* Copyright (c) 2013-2019 Nikita Koksharov
*
* 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.
*/
package org.redisson.hibernate.strategy;
import org.hibernate.cache.CacheException;
import org.hibernate.cache.spi.GeneralDataRegion;
import org.hibernate.cache.spi.NaturalIdRegion;
import org.hibernate.cache.spi.access.NaturalIdRegionAccessStrategy;
import org.hibernate.cache.spi.access.SoftLock;
import org.hibernate.cfg.Settings;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.persister.entity.EntityPersister;
import org.redisson.hibernate.region.RedissonNaturalIdRegion;
/**
*
* @author Nikita Koksharov
*
*/
public class NonStrictReadWriteNaturalIdRegionAccessStrategy extends BaseRegionAccessStrategy implements NaturalIdRegionAccessStrategy {
public NonStrictReadWriteNaturalIdRegionAccessStrategy(Settings settings, GeneralDataRegion region) {
super(settings, region);
}
@Override
public Object get(SharedSessionContractImplementor session, Object key, long txTimestamp) throws CacheException {
return region.get(session, key);
}
@Override
public boolean putFromLoad(SharedSessionContractImplementor session, Object key, Object value, long txTimestamp, Object version, boolean minimalPutOverride)
throws CacheException {
if (minimalPutOverride && region.contains(key)) {
return false;
}
region.put(session, key, value);
return true;
}
@Override
public SoftLock lockItem(SharedSessionContractImplementor session, Object key, Object version) throws CacheException {
return null;
}
@Override
public void unlockItem(SharedSessionContractImplementor session, Object key, SoftLock lock) throws CacheException {
evict(key);
}
@Override
public NaturalIdRegion getRegion() {
return (NaturalIdRegion) region;
}
@Override
public boolean insert(SharedSessionContractImplementor session, Object key, Object value) throws CacheException {
return false;
}
@Override
public boolean afterInsert(SharedSessionContractImplementor session, Object key, Object value) throws CacheException {
return false;
}
@Override
public boolean update(SharedSessionContractImplementor session, Object key, Object value) throws CacheException {
remove(session, key);
return false;
}
@Override
public boolean afterUpdate(SharedSessionContractImplementor session, Object key, Object value, SoftLock lock) throws CacheException {
unlockItem(session, key, lock);
return false;
}
@Override
public void remove(SharedSessionContractImplementor session, Object key) throws CacheException {
region.evict(key);
}
@Override
public Object generateCacheKey(Object[] naturalIdValues, EntityPersister persister, SharedSessionContractImplementor session) {
return ((RedissonNaturalIdRegion)region).getCacheKeysFactory().createNaturalIdKey(naturalIdValues, persister, session);
}
@Override
public Object[] getNaturalIdValues(Object cacheKey) {
return ((RedissonNaturalIdRegion)region).getCacheKeysFactory().getNaturalIdValues(cacheKey);
}
}

@ -1,80 +0,0 @@
/**
* Copyright (c) 2013-2019 Nikita Koksharov
*
* 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.
*/
package org.redisson.hibernate.strategy;
import org.hibernate.cache.CacheException;
import org.hibernate.cache.spi.CollectionRegion;
import org.hibernate.cache.spi.GeneralDataRegion;
import org.hibernate.cache.spi.access.CollectionRegionAccessStrategy;
import org.hibernate.cache.spi.access.SoftLock;
import org.hibernate.cfg.Settings;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.persister.collection.CollectionPersister;
import org.redisson.hibernate.region.RedissonCollectionRegion;
/**
*
* @author Nikita Koksharov
*
*/
public class ReadOnlyCollectionRegionAccessStrategy extends BaseRegionAccessStrategy implements CollectionRegionAccessStrategy {
public ReadOnlyCollectionRegionAccessStrategy(Settings settings, GeneralDataRegion region) {
super(settings, region);
}
@Override
public CollectionRegion getRegion() {
return (CollectionRegion) region;
}
@Override
public Object get(SharedSessionContractImplementor session, Object key, long txTimestamp) throws CacheException {
return region.get(session, key);
}
@Override
public boolean putFromLoad(SharedSessionContractImplementor session, Object key, Object value, long txTimestamp, Object version, boolean minimalPutOverride)
throws CacheException {
if (minimalPutOverride && region.contains(key)) {
return false;
}
region.put(session, key, value);
return true;
}
@Override
public SoftLock lockItem(SharedSessionContractImplementor session, Object key, Object version) throws CacheException {
return null;
}
@Override
public void unlockItem(SharedSessionContractImplementor session, Object key, SoftLock lock) throws CacheException {
}
@Override
public Object generateCacheKey(Object id, CollectionPersister persister, SessionFactoryImplementor factory, String tenantIdentifier) {
return ((RedissonCollectionRegion)region).getCacheKeysFactory().createCollectionKey(id, persister, factory, tenantIdentifier);
}
@Override
public Object getCacheKeyId(Object cacheKey) {
return ((RedissonCollectionRegion)region).getCacheKeysFactory().getCollectionId(cacheKey);
}
}

@ -1,104 +0,0 @@
/**
* Copyright (c) 2013-2019 Nikita Koksharov
*
* 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.
*/
package org.redisson.hibernate.strategy;
import org.hibernate.cache.CacheException;
import org.hibernate.cache.spi.EntityRegion;
import org.hibernate.cache.spi.GeneralDataRegion;
import org.hibernate.cache.spi.access.EntityRegionAccessStrategy;
import org.hibernate.cache.spi.access.SoftLock;
import org.hibernate.cfg.Settings;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.persister.entity.EntityPersister;
import org.redisson.hibernate.region.RedissonEntityRegion;
/**
*
* @author Nikita Koksharov
*
*/
public class ReadOnlyEntityRegionAccessStrategy extends BaseRegionAccessStrategy implements EntityRegionAccessStrategy {
public ReadOnlyEntityRegionAccessStrategy(Settings settings, GeneralDataRegion region) {
super(settings, region);
}
@Override
public Object get(SharedSessionContractImplementor session, Object key, long txTimestamp) throws CacheException {
return region.get(session, key);
}
@Override
public boolean putFromLoad(SharedSessionContractImplementor session, Object key, Object value, long txTimestamp, Object version, boolean minimalPutOverride)
throws CacheException {
if (minimalPutOverride && region.contains(key)) {
return false;
}
region.put(session, key, value);
return true;
}
@Override
public SoftLock lockItem(SharedSessionContractImplementor session, Object key, Object version) throws CacheException {
return null;
}
@Override
public void unlockItem(SharedSessionContractImplementor session, Object key, SoftLock lock) throws CacheException {
evict(key);
}
@Override
public EntityRegion getRegion() {
return (EntityRegion) region;
}
@Override
public boolean insert(SharedSessionContractImplementor session, Object key, Object value, Object version) throws CacheException {
return false;
}
@Override
public boolean afterInsert(SharedSessionContractImplementor session, Object key, Object value, Object version) throws CacheException {
region.put(session, key, value);
return true;
}
@Override
public boolean update(SharedSessionContractImplementor session, Object key, Object value, Object currentVersion, Object previousVersion)
throws CacheException {
throw new UnsupportedOperationException("Unable to update read-only object");
}
@Override
public boolean afterUpdate(SharedSessionContractImplementor session, Object key, Object value, Object currentVersion, Object previousVersion, SoftLock lock)
throws CacheException {
throw new UnsupportedOperationException("Unable to update read-only object");
}
@Override
public Object generateCacheKey(Object id, EntityPersister persister, SessionFactoryImplementor factory, String tenantIdentifier) {
return ((RedissonEntityRegion)region).getCacheKeysFactory().createEntityKey( id, persister, factory, tenantIdentifier );
}
@Override
public Object getCacheKeyId(Object cacheKey) {
return ((RedissonEntityRegion)region).getCacheKeysFactory().getEntityId(cacheKey);
}
}

@ -1,101 +0,0 @@
/**
* Copyright (c) 2013-2019 Nikita Koksharov
*
* 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.
*/
package org.redisson.hibernate.strategy;
import org.hibernate.cache.CacheException;
import org.hibernate.cache.spi.GeneralDataRegion;
import org.hibernate.cache.spi.NaturalIdRegion;
import org.hibernate.cache.spi.access.NaturalIdRegionAccessStrategy;
import org.hibernate.cache.spi.access.SoftLock;
import org.hibernate.cfg.Settings;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.persister.entity.EntityPersister;
import org.redisson.hibernate.region.RedissonNaturalIdRegion;
/**
*
* @author Nikita Koksharov
*
*/
public class ReadOnlyNaturalIdRegionAccessStrategy extends BaseRegionAccessStrategy implements NaturalIdRegionAccessStrategy {
public ReadOnlyNaturalIdRegionAccessStrategy(Settings settings, GeneralDataRegion region) {
super(settings, region);
}
@Override
public Object get(SharedSessionContractImplementor session, Object key, long txTimestamp) throws CacheException {
return region.get(session, key);
}
@Override
public boolean putFromLoad(SharedSessionContractImplementor session, Object key, Object value, long txTimestamp, Object version, boolean minimalPutOverride)
throws CacheException {
if (minimalPutOverride && region.contains(key)) {
return false;
}
region.put(session, key, value);
return true;
}
@Override
public SoftLock lockItem(SharedSessionContractImplementor session, Object key, Object version) throws CacheException {
return null;
}
@Override
public void unlockItem(SharedSessionContractImplementor session, Object key, SoftLock lock) throws CacheException {
evict(key);
}
@Override
public NaturalIdRegion getRegion() {
return (NaturalIdRegion) region;
}
@Override
public boolean insert(SharedSessionContractImplementor session, Object key, Object value) throws CacheException {
return false;
}
@Override
public boolean afterInsert(SharedSessionContractImplementor session, Object key, Object value) throws CacheException {
region.put(session, key, value);
return true;
}
@Override
public boolean update(SharedSessionContractImplementor session, Object key, Object value) throws CacheException {
throw new UnsupportedOperationException("Unable to update read-only object");
}
@Override
public boolean afterUpdate(SharedSessionContractImplementor session, Object key, Object value, SoftLock lock) throws CacheException {
throw new UnsupportedOperationException("Unable to update read-only object");
}
@Override
public Object generateCacheKey(Object[] naturalIdValues, EntityPersister persister, SharedSessionContractImplementor session) {
return ((RedissonNaturalIdRegion)region).getCacheKeysFactory().createNaturalIdKey(naturalIdValues, persister, session);
}
@Override
public Object[] getNaturalIdValues(Object cacheKey) {
return ((RedissonNaturalIdRegion)region).getCacheKeysFactory().getNaturalIdValues(cacheKey);
}
}

@ -1,54 +0,0 @@
/**
* Copyright (c) 2013-2019 Nikita Koksharov
*
* 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.
*/
package org.redisson.hibernate.strategy;
import org.hibernate.cache.spi.CollectionRegion;
import org.hibernate.cache.spi.GeneralDataRegion;
import org.hibernate.cache.spi.access.CollectionRegionAccessStrategy;
import org.hibernate.cfg.Settings;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.persister.collection.CollectionPersister;
import org.redisson.api.RMapCache;
import org.redisson.hibernate.region.RedissonCollectionRegion;
/**
*
* @author Nikita Koksharov
*
*/
public class ReadWriteCollectionRegionAccessStrategy extends AbstractReadWriteAccessStrategy implements CollectionRegionAccessStrategy {
public ReadWriteCollectionRegionAccessStrategy(Settings settings, GeneralDataRegion region,
RMapCache<Object, Object> mapCache) {
super(settings, region, mapCache);
}
@Override
public CollectionRegion getRegion() {
return (CollectionRegion) region;
}
@Override
public Object generateCacheKey(Object id, CollectionPersister persister, SessionFactoryImplementor factory, String tenantIdentifier) {
return ((RedissonCollectionRegion)region).getCacheKeysFactory().createCollectionKey( id, persister, factory, tenantIdentifier );
}
@Override
public Object getCacheKeyId(Object cacheKey) {
return ((RedissonCollectionRegion)region).getCacheKeysFactory().getCollectionId(cacheKey);
}
}

@ -1,135 +0,0 @@
/**
* Copyright (c) 2013-2019 Nikita Koksharov
*
* 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.
*/
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2010-2011, Red Hat Inc. or third-party contributors as
* indicated by the @author tags or express copyright attribution
* statements applied by the authors. All third-party contributions are
* distributed under license by Red Hat Inc.
*
* This copyrighted material is made available to anyone wishing to use, modify,
* copy, or redistribute it subject to the terms and conditions of the GNU
* Lesser General Public License, as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this distribution; if not, write to:
* Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
package org.redisson.hibernate.strategy;
import org.hibernate.cache.CacheException;
import org.hibernate.cache.spi.EntityRegion;
import org.hibernate.cache.spi.GeneralDataRegion;
import org.hibernate.cache.spi.access.EntityRegionAccessStrategy;
import org.hibernate.cache.spi.access.SoftLock;
import org.hibernate.cfg.Settings;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.persister.entity.EntityPersister;
import org.redisson.api.RLock;
import org.redisson.api.RMapCache;
import org.redisson.hibernate.region.RedissonEntityRegion;
/**
*
* @author Nikita Koksharov
* @author Strong Liu
*
*/
public class ReadWriteEntityRegionAccessStrategy extends AbstractReadWriteAccessStrategy implements EntityRegionAccessStrategy {
public ReadWriteEntityRegionAccessStrategy(Settings settings, GeneralDataRegion region, RMapCache<Object, Object> mapCache) {
super(settings, region, mapCache);
}
@Override
public EntityRegion getRegion() {
return (EntityRegion) region;
}
@Override
public boolean insert(SharedSessionContractImplementor session, Object key, Object value, Object version) throws CacheException {
return false;
}
@Override
public boolean afterInsert(SharedSessionContractImplementor session, Object key, Object value, Object version) throws CacheException {
RLock writeLock = mapCache.getReadWriteLock(key).writeLock();
writeLock.lock();
try {
Lockable item = (Lockable) region.get(session, key);
if (item == null) {
region.put(session, key, new Item(value, version, region.nextTimestamp()));
return true;
} else {
return false;
}
} finally {
writeLock.unlock();
}
}
@Override
public boolean update(SharedSessionContractImplementor session, Object key, Object value, Object currentVersion, Object previousVersion)
throws CacheException {
return false;
}
@Override
public boolean afterUpdate(SharedSessionContractImplementor session, Object key, Object value, Object currentVersion, Object previousVersion, SoftLock lock)
throws CacheException {
RLock writeLock = mapCache.getReadWriteLock(key).writeLock();
writeLock.lock();
try {
Lockable item = (Lockable) region.get(session, key);
if (item != null && item.isUnlockable(lock)) {
Lock lockItem = (Lock) item;
if (lockItem.wasLockedConcurrently()) {
decrementLock(session, key, lockItem );
return false;
} else {
region.put(session, key, new Item(value, currentVersion, region.nextTimestamp()));
return true;
}
} else {
handleLockExpiry(session, key, item );
return false;
}
} finally {
writeLock.unlock();
}
}
@Override
public Object generateCacheKey(Object id, EntityPersister persister, SessionFactoryImplementor factory, String tenantIdentifier) {
return ((RedissonEntityRegion)region).getCacheKeysFactory().createEntityKey(id, persister, factory, tenantIdentifier);
}
@Override
public Object getCacheKeyId(Object cacheKey) {
return ((RedissonEntityRegion)region).getCacheKeysFactory().getEntityId(cacheKey);
}
}

@ -1,133 +0,0 @@
/**
* Copyright (c) 2013-2019 Nikita Koksharov
*
* 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.
*/
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2010-2011, Red Hat Inc. or third-party contributors as
* indicated by the @author tags or express copyright attribution
* statements applied by the authors. All third-party contributions are
* distributed under license by Red Hat Inc.
*
* This copyrighted material is made available to anyone wishing to use, modify,
* copy, or redistribute it subject to the terms and conditions of the GNU
* Lesser General Public License, as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this distribution; if not, write to:
* Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
package org.redisson.hibernate.strategy;
import org.hibernate.cache.CacheException;
import org.hibernate.cache.spi.GeneralDataRegion;
import org.hibernate.cache.spi.NaturalIdRegion;
import org.hibernate.cache.spi.access.NaturalIdRegionAccessStrategy;
import org.hibernate.cache.spi.access.SoftLock;
import org.hibernate.cfg.Settings;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.persister.entity.EntityPersister;
import org.redisson.api.RLock;
import org.redisson.api.RMapCache;
import org.redisson.hibernate.region.RedissonNaturalIdRegion;
/**
*
* @author Nikita Koksharov
* @author Eric Dalquist
*
*/
public class ReadWriteNaturalIdRegionAccessStrategy extends AbstractReadWriteAccessStrategy implements NaturalIdRegionAccessStrategy {
public ReadWriteNaturalIdRegionAccessStrategy(Settings settings, GeneralDataRegion region,
RMapCache<Object, Object> mapCache) {
super(settings, region, mapCache);
}
@Override
public NaturalIdRegion getRegion() {
return (NaturalIdRegion) region;
}
@Override
public boolean insert(SharedSessionContractImplementor session, Object key, Object value) throws CacheException {
return false;
}
@Override
public boolean afterInsert(SharedSessionContractImplementor session, Object key, Object value) throws CacheException {
RLock writeLock = mapCache.getReadWriteLock(key).writeLock();
writeLock.lock();
try {
Lockable item = (Lockable) region.get(session, key);
if (item == null) {
region.put(session, key, new Item(value, null, region.nextTimestamp()));
return true;
} else {
return false;
}
} finally {
writeLock.unlock();
}
}
@Override
public boolean update(SharedSessionContractImplementor session, Object key, Object value) throws CacheException {
return false;
}
@Override
public boolean afterUpdate(SharedSessionContractImplementor session, Object key, Object value, SoftLock lock) throws CacheException {
RLock writeLock = mapCache.getReadWriteLock(key).writeLock();
writeLock.lock();
try {
Lockable item = (Lockable) region.get(session, key);
if (item != null && item.isUnlockable(lock)) {
Lock lockItem = (Lock) item;
if (lockItem.wasLockedConcurrently()) {
decrementLock(session, key, lockItem);
return false;
} else {
region.put(session, key, new Item(value, null, region.nextTimestamp()));
return true;
}
} else {
handleLockExpiry(session, key, item);
return false;
}
} finally {
writeLock.unlock();
}
}
@Override
public Object generateCacheKey(Object[] naturalIdValues, EntityPersister persister, SharedSessionContractImplementor session) {
return ((RedissonNaturalIdRegion)region).getCacheKeysFactory().createNaturalIdKey(naturalIdValues, persister, session);
}
@Override
public Object[] getNaturalIdValues(Object cacheKey) {
return ((RedissonNaturalIdRegion)region).getCacheKeysFactory().getNaturalIdValues(cacheKey);
}
}

@ -1,85 +0,0 @@
/**
* Copyright (c) 2013-2019 Nikita Koksharov
*
* 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.
*/
package org.redisson.hibernate.strategy;
import org.hibernate.cache.CacheException;
import org.hibernate.cache.spi.CollectionRegion;
import org.hibernate.cache.spi.GeneralDataRegion;
import org.hibernate.cache.spi.access.CollectionRegionAccessStrategy;
import org.hibernate.cache.spi.access.SoftLock;
import org.hibernate.cfg.Settings;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.persister.collection.CollectionPersister;
import org.redisson.hibernate.region.RedissonCollectionRegion;
/**
*
* @author Nikita Koksharov
*
*/
public class TransactionalCollectionRegionAccessStrategy extends BaseRegionAccessStrategy implements CollectionRegionAccessStrategy {
public TransactionalCollectionRegionAccessStrategy(Settings settings, GeneralDataRegion region) {
super(settings, region);
}
@Override
public CollectionRegion getRegion() {
return (CollectionRegion) region;
}
@Override
public Object get(SharedSessionContractImplementor session, Object key, long txTimestamp) throws CacheException {
return region.get(session, key);
}
@Override
public boolean putFromLoad(SharedSessionContractImplementor session, Object key, Object value, long txTimestamp, Object version, boolean minimalPutOverride)
throws CacheException {
if (minimalPutOverride && region.contains(key)) {
return false;
}
region.put(session, key, value);
return true;
}
@Override
public SoftLock lockItem(SharedSessionContractImplementor session, Object key, Object version) throws CacheException {
return null;
}
@Override
public void unlockItem(SharedSessionContractImplementor session, Object key, SoftLock lock) throws CacheException {
}
@Override
public void remove(SharedSessionContractImplementor session, Object key) throws CacheException {
region.evict(key);
}
@Override
public Object generateCacheKey(Object id, CollectionPersister persister, SessionFactoryImplementor factory, String tenantIdentifier) {
return ((RedissonCollectionRegion)region).getCacheKeysFactory().createCollectionKey( id, persister, factory, tenantIdentifier );
}
@Override
public Object getCacheKeyId(Object cacheKey) {
return ((RedissonCollectionRegion)region).getCacheKeysFactory().getCollectionId(cacheKey);
}
}

@ -1,108 +0,0 @@
/**
* Copyright (c) 2013-2019 Nikita Koksharov
*
* 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.
*/
package org.redisson.hibernate.strategy;
import org.hibernate.cache.CacheException;
import org.hibernate.cache.spi.EntityRegion;
import org.hibernate.cache.spi.GeneralDataRegion;
import org.hibernate.cache.spi.access.EntityRegionAccessStrategy;
import org.hibernate.cache.spi.access.SoftLock;
import org.hibernate.cfg.Settings;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.persister.entity.EntityPersister;
import org.redisson.hibernate.region.RedissonEntityRegion;
/**
*
* @author Nikita Koksharov
*
*/
public class TransactionalEntityRegionAccessStrategy extends BaseRegionAccessStrategy implements EntityRegionAccessStrategy {
public TransactionalEntityRegionAccessStrategy(Settings settings, GeneralDataRegion region) {
super(settings, region);
}
@Override
public Object get(SharedSessionContractImplementor session, Object key, long txTimestamp) throws CacheException {
return region.get(session, key);
}
@Override
public boolean putFromLoad(SharedSessionContractImplementor session, Object key, Object value, long txTimestamp, Object version, boolean minimalPutOverride)
throws CacheException {
if (minimalPutOverride && region.contains(key)) {
return false;
}
region.put(session, key, value);
return true;
}
@Override
public SoftLock lockItem(SharedSessionContractImplementor session, Object key, Object version) throws CacheException {
return null;
}
@Override
public void unlockItem(SharedSessionContractImplementor session, Object key, SoftLock lock) throws CacheException {
}
@Override
public EntityRegion getRegion() {
return (EntityRegion) region;
}
@Override
public boolean insert(SharedSessionContractImplementor session, Object key, Object value, Object version) throws CacheException {
region.put(session, key, value);
return true;
}
@Override
public boolean afterInsert(SharedSessionContractImplementor session, Object key, Object value, Object version) throws CacheException {
return false;
}
@Override
public void remove(SharedSessionContractImplementor session, Object key) throws CacheException {
region.evict(key);
}
@Override
public boolean update(SharedSessionContractImplementor session, Object key, Object value, Object currentVersion, Object previousVersion)
throws CacheException {
return insert(session, key, value, currentVersion);
}
@Override
public boolean afterUpdate(SharedSessionContractImplementor session, Object key, Object value, Object currentVersion, Object previousVersion, SoftLock lock)
throws CacheException {
return false;
}
@Override
public Object generateCacheKey(Object id, EntityPersister persister, SessionFactoryImplementor factory, String tenantIdentifier) {
return ((RedissonEntityRegion)region).getCacheKeysFactory().createEntityKey(id, persister, factory, tenantIdentifier);
}
@Override
public Object getCacheKeyId(Object cacheKey) {
return ((RedissonEntityRegion)region).getCacheKeysFactory().getEntityId(cacheKey);
}
}

@ -1,105 +0,0 @@
/**
* Copyright (c) 2013-2019 Nikita Koksharov
*
* 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.
*/
package org.redisson.hibernate.strategy;
import org.hibernate.cache.CacheException;
import org.hibernate.cache.spi.GeneralDataRegion;
import org.hibernate.cache.spi.NaturalIdRegion;
import org.hibernate.cache.spi.access.NaturalIdRegionAccessStrategy;
import org.hibernate.cache.spi.access.SoftLock;
import org.hibernate.cfg.Settings;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.persister.entity.EntityPersister;
import org.redisson.hibernate.region.RedissonNaturalIdRegion;
/**
*
* @author Nikita Koksharov
*
*/
public class TransactionalNaturalIdRegionAccessStrategy extends BaseRegionAccessStrategy implements NaturalIdRegionAccessStrategy {
public TransactionalNaturalIdRegionAccessStrategy(Settings settings, GeneralDataRegion region) {
super(settings, region);
}
@Override
public Object get(SharedSessionContractImplementor session, Object key, long txTimestamp) throws CacheException {
return region.get(session, key);
}
@Override
public boolean putFromLoad(SharedSessionContractImplementor session, Object key, Object value, long txTimestamp, Object version, boolean minimalPutOverride)
throws CacheException {
if (minimalPutOverride && region.contains(key)) {
return false;
}
region.put(session, key, value);
return true;
}
@Override
public SoftLock lockItem(SharedSessionContractImplementor session, Object key, Object version) throws CacheException {
return null;
}
@Override
public void unlockItem(SharedSessionContractImplementor session, Object key, SoftLock lock) throws CacheException {
}
@Override
public NaturalIdRegion getRegion() {
return (NaturalIdRegion) region;
}
@Override
public void remove(SharedSessionContractImplementor session, Object key) throws CacheException {
region.evict(key);
}
@Override
public boolean insert(SharedSessionContractImplementor session, Object key, Object value) throws CacheException {
region.put(session, key, value);
return true;
}
@Override
public boolean afterInsert(SharedSessionContractImplementor session, Object key, Object value) throws CacheException {
return false;
}
@Override
public boolean update(SharedSessionContractImplementor session, Object key, Object value) throws CacheException {
return insert(session, key, value);
}
@Override
public boolean afterUpdate(SharedSessionContractImplementor session, Object key, Object value, SoftLock lock) throws CacheException {
return false;
}
@Override
public Object generateCacheKey(Object[] naturalIdValues, EntityPersister persister, SharedSessionContractImplementor session) {
return ((RedissonNaturalIdRegion)region).getCacheKeysFactory().createNaturalIdKey(naturalIdValues, persister, session);
}
@Override
public Object[] getNaturalIdValues(Object cacheKey) {
return ((RedissonNaturalIdRegion)region).getCacheKeysFactory().getNaturalIdValues(cacheKey);
}
}

@ -1,11 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<blueprint default-activation="eager"
xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<bean id="strategyRegistrationProvider" class="org.redisson.hibernate.RedissonStrategyRegistrationProvider"/>
<service ref="strategyRegistrationProvider" interface="org.hibernate.boot.registry.selector.StrategyRegistrationProvider"/>
</blueprint>

@ -1,84 +0,0 @@
package org.redisson.hibernate;
import java.util.ArrayList;
import java.util.List;
import javax.persistence.Column;
import javax.persistence.ElementCollection;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import org.hibernate.annotations.Cache;
import org.hibernate.annotations.CacheConcurrencyStrategy;
import org.hibernate.annotations.GenericGenerator;
import org.hibernate.annotations.NaturalId;
import org.hibernate.annotations.NaturalIdCache;
/**
*
* @author Nikita Koksharov
*
*/
@Entity
@NamedQueries(@NamedQuery(name = "testQuery", query = "from ItemReadWrite where name = :name"))
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE, region = "item")
@NaturalIdCache
public class ItemReadWrite {
@Id
@GeneratedValue(generator = "increment")
@GenericGenerator(name = "increment", strategy = "increment")
private Long id;
private String name;
@NaturalId
private String nid;
@ElementCollection
@JoinTable(name = "Entries", joinColumns = @JoinColumn(name="Item_id"))
@Column(name = "entry", nullable = false)
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE, region = "item_entries")
private List<String> entries = new ArrayList<String>();
public ItemReadWrite() {
}
public ItemReadWrite(String name) {
this.name = name;
}
public String getNid() {
return nid;
}
public void setNid(String nid) {
this.nid = nid;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<String> getEntries() {
return entries;
}
}

@ -1,84 +0,0 @@
package org.redisson.hibernate;
import java.util.ArrayList;
import java.util.List;
import javax.persistence.Column;
import javax.persistence.ElementCollection;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import org.hibernate.annotations.Cache;
import org.hibernate.annotations.CacheConcurrencyStrategy;
import org.hibernate.annotations.GenericGenerator;
import org.hibernate.annotations.NaturalId;
import org.hibernate.annotations.NaturalIdCache;
/**
*
* @author Nikita Koksharov
*
*/
@Entity
@NamedQueries(@NamedQuery(name = "testQuery", query = "from ItemTransactional where name = :name"))
@Cache(usage = CacheConcurrencyStrategy.TRANSACTIONAL, region = "item")
@NaturalIdCache
public class ItemTransactional {
@Id
@GeneratedValue(generator = "increment")
@GenericGenerator(name = "increment", strategy = "increment")
private Long id;
private String name;
@NaturalId
private String nid;
@ElementCollection
@JoinTable(name = "Entries", joinColumns = @JoinColumn(name="Item_id"))
@Column(name = "entry", nullable = false)
@Cache(usage = CacheConcurrencyStrategy.TRANSACTIONAL, region = "item_entries")
private List<String> entries = new ArrayList<String>();
public ItemTransactional() {
}
public ItemTransactional(String name) {
this.name = name;
}
public String getNid() {
return nid;
}
public void setNid(String nid) {
this.nid = nid;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<String> getEntries() {
return entries;
}
}

@ -1,236 +0,0 @@
package org.redisson.hibernate;
import static org.assertj.core.api.Assertions.assertThat;
import java.util.Arrays;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.cfg.Configuration;
import org.hibernate.cfg.Environment;
import org.hibernate.stat.Statistics;
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.redisson.hibernate.RedissonRegionFactory;
/**
*
* @author Nikita Koksharov
*
*/
public class ReadWriteTest extends BaseCoreFunctionalTestCase {
@Override
protected Class<?>[] getAnnotatedClasses() {
return new Class[] { ItemReadWrite.class};
}
@Override
protected void configure(Configuration cfg) {
super.configure(cfg);
cfg.setProperty(Environment.DRIVER, org.h2.Driver.class.getName());
cfg.setProperty(Environment.URL, "jdbc:h2:mem:db1;DB_CLOSE_DELAY=-1;MVCC=TRUE");
cfg.setProperty(Environment.USER, "sa");
cfg.setProperty(Environment.PASS, "");
cfg.setProperty(Environment.CACHE_REGION_PREFIX, "");
cfg.setProperty(Environment.GENERATE_STATISTICS, "true");
cfg.setProperty(Environment.USE_SECOND_LEVEL_CACHE, "true");
cfg.setProperty(Environment.USE_QUERY_CACHE, "true");
cfg.setProperty(Environment.CACHE_REGION_FACTORY, RedissonRegionFactory.class.getName());
cfg.setProperty("hibernate.cache.redisson.item.eviction.max_entries", "100");
cfg.setProperty("hibernate.cache.redisson.item.expiration.time_to_live", "1500");
cfg.setProperty("hibernate.cache.redisson.item.expiration.max_idle_time", "1000");
cfg.setProperty("hibernate.cache.redisson.item##NaturalId.eviction.max_entries", "1000");
cfg.setProperty("hibernate.cache.redisson.item##NaturalId.expiration.time_to_live", "1100");
cfg.setProperty("hibernate.cache.redisson.item##NaturalId.expiration.max_idle_time", "1200");
}
@Before
public void before() {
sessionFactory().getCache().evictEntityRegions();
sessionFactory().getStatistics().clear();
}
@Test
public void testTimeToLive() throws InterruptedException {
Statistics stats = sessionFactory().getStatistics();
Long id = null;
Session s = openSession();
s.beginTransaction();
ItemReadWrite item = new ItemReadWrite( "data" );
id = (Long) s.save( item );
s.flush();
s.getTransaction().commit();
s.close();
Thread.sleep(900);
s = openSession();
s.beginTransaction();
item = (ItemReadWrite) s.get(ItemReadWrite.class, id);
Assert.assertEquals("data", item.getName());
s.getTransaction().commit();
s.close();
Assert.assertEquals(1, stats.getSecondLevelCacheStatistics("item").getHitCount());
Assert.assertEquals(0, stats.getSecondLevelCacheStatistics("item").getMissCount());
Thread.sleep(600);
s = openSession();
s.beginTransaction();
item = (ItemReadWrite) s.get(ItemReadWrite.class, id);
Assert.assertEquals("data", item.getName());
s.delete(item);
s.getTransaction().commit();
s.close();
Assert.assertEquals(1, stats.getSecondLevelCacheStatistics("item").getHitCount());
Assert.assertEquals(1, stats.getSecondLevelCacheStatistics("item").getMissCount());
}
@Test
public void testQuery() {
Statistics stats = sessionFactory().getStatistics();
Session s = openSession();
s.beginTransaction();
ItemReadWrite item = new ItemReadWrite("data");
item.getEntries().addAll(Arrays.asList("a", "b", "c"));
s.save(item);
s.flush();
s.getTransaction().commit();
s = openSession();
s.beginTransaction();
Query query = s.getNamedQuery("testQuery");
query.setCacheable(true);
query.setCacheRegion("myTestQuery");
query.setParameter("name", "data");
item = (ItemReadWrite) query.uniqueResult();
s.getTransaction().commit();
s.close();
Assert.assertEquals(1, stats.getSecondLevelCacheStatistics("myTestQuery").getPutCount());
s = openSession();
s.beginTransaction();
Query query2 = s.getNamedQuery("testQuery");
query2.setCacheable(true);
query2.setCacheRegion("myTestQuery");
query2.setParameter("name", "data");
item = (ItemReadWrite) query2.uniqueResult();
s.delete(item);
s.getTransaction().commit();
s.close();
Assert.assertEquals(1, stats.getSecondLevelCacheStatistics("myTestQuery").getHitCount());
stats.logSummary();
}
@Test
public void testCollection() {
Long id = null;
Statistics stats = sessionFactory().getStatistics();
Session s = openSession();
s.beginTransaction();
ItemReadWrite item = new ItemReadWrite("data");
item.getEntries().addAll(Arrays.asList("a", "b", "c"));
id = (Long) s.save(item);
s.flush();
s.getTransaction().commit();
s = openSession();
s.beginTransaction();
item = (ItemReadWrite) s.get(ItemReadWrite.class, id);
assertThat(item.getEntries()).containsExactly("a", "b", "c");
s.getTransaction().commit();
s.close();
Assert.assertEquals(1, stats.getSecondLevelCacheStatistics("item_entries").getPutCount());
s = openSession();
s.beginTransaction();
item = (ItemReadWrite) s.get(ItemReadWrite.class, id);
assertThat(item.getEntries()).containsExactly("a", "b", "c");
s.delete(item);
s.getTransaction().commit();
s.close();
Assert.assertEquals(1, stats.getSecondLevelCacheStatistics("item_entries").getHitCount());
}
@Test
public void testNaturalId() {
Statistics stats = sessionFactory().getStatistics();
Session s = openSession();
s.beginTransaction();
ItemReadWrite item = new ItemReadWrite("data");
item.setNid("123");
s.save(item);
s.flush();
s.getTransaction().commit();
Assert.assertEquals(1, stats.getSecondLevelCacheStatistics("item").getPutCount());
Assert.assertEquals(1, stats.getNaturalIdCacheStatistics("item##NaturalId").getPutCount());
s = openSession();
s.beginTransaction();
item = (ItemReadWrite) s.bySimpleNaturalId(ItemReadWrite.class).load("123");
assertThat(item).isNotNull();
s.delete(item);
s.getTransaction().commit();
s.close();
Assert.assertEquals(1, stats.getSecondLevelCacheStatistics("item").getHitCount());
Assert.assertEquals(1, stats.getNaturalIdCacheStatistics("item##NaturalId").getHitCount());
sessionFactory().getStatistics().logSummary();
}
@Test
public void testUpdateWithRefreshThenRollback() {
Statistics stats = sessionFactory().getStatistics();
Long id = null;
Session s = openSession();
s.beginTransaction();
ItemReadWrite item = new ItemReadWrite( "data" );
id = (Long) s.save( item );
s.flush();
s.getTransaction().commit();
Assert.assertEquals(1, stats.getSecondLevelCacheStatistics("item").getPutCount());
s = openSession();
s.beginTransaction();
item = (ItemReadWrite) s.get(ItemReadWrite.class, id);
item.setName("newdata");
s.update(item);
s.flush();
s.refresh(item);
s.getTransaction().rollback();
s.clear();
s.close();
s = openSession();
s.beginTransaction();
item = (ItemReadWrite) s.get(ItemReadWrite.class, id);
Assert.assertEquals("data", item.getName());
s.delete(item);
s.getTransaction().commit();
s.close();
Assert.assertEquals(1, stats.getSecondLevelCacheStatistics("item").getHitCount());
}
}

@ -1,181 +0,0 @@
package org.redisson.hibernate;
import static org.assertj.core.api.Assertions.assertThat;
import java.util.Arrays;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.cfg.Configuration;
import org.hibernate.cfg.Environment;
import org.hibernate.stat.Statistics;
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.redisson.hibernate.RedissonRegionFactory;
/**
*
* @author Nikita Koksharov
*
*/
public class TransactionalTest extends BaseCoreFunctionalTestCase {
@Override
protected Class<?>[] getAnnotatedClasses() {
return new Class[] { ItemTransactional.class};
}
@Override
protected void configure(Configuration cfg) {
super.configure(cfg);
cfg.setProperty(Environment.DRIVER, org.h2.Driver.class.getName());
cfg.setProperty(Environment.URL, "jdbc:h2:mem:db1;DB_CLOSE_DELAY=-1;MVCC=TRUE");
cfg.setProperty(Environment.USER, "sa");
cfg.setProperty(Environment.PASS, "");
cfg.setProperty(Environment.CACHE_REGION_PREFIX, "");
cfg.setProperty(Environment.GENERATE_STATISTICS, "true");
cfg.setProperty(Environment.USE_SECOND_LEVEL_CACHE, "true");
cfg.setProperty(Environment.USE_QUERY_CACHE, "true");
cfg.setProperty(Environment.CACHE_REGION_FACTORY, RedissonRegionFactory.class.getName());
}
@Before
public void before() {
sessionFactory().getCache().evictEntityRegions();
sessionFactory().getStatistics().clear();
}
@Test
public void testQuery() {
Statistics stats = sessionFactory().getStatistics();
Session s = openSession();
s.beginTransaction();
ItemTransactional item = new ItemTransactional("data");
item.getEntries().addAll(Arrays.asList("a", "b", "c"));
s.save(item);
s.flush();
s.getTransaction().commit();
s = openSession();
s.beginTransaction();
Query query = s.getNamedQuery("testQuery");
query.setCacheable(true);
query.setCacheRegion("myTestQuery");
query.setParameter("name", "data");
item = (ItemTransactional) query.uniqueResult();
s.getTransaction().commit();
s.close();
Assert.assertEquals(1, stats.getSecondLevelCacheStatistics("myTestQuery").getPutCount());
s = openSession();
s.beginTransaction();
Query query2 = s.getNamedQuery("testQuery");
query2.setCacheable(true);
query2.setCacheRegion("myTestQuery");
query2.setParameter("name", "data");
item = (ItemTransactional) query2.uniqueResult();
s.delete(item);
s.getTransaction().commit();
s.close();
Assert.assertEquals(1, stats.getSecondLevelCacheStatistics("myTestQuery").getHitCount());
stats.logSummary();
}
@Test
public void testCollection() {
Long id = null;
Statistics stats = sessionFactory().getStatistics();
Session s = openSession();
s.beginTransaction();
ItemTransactional item = new ItemTransactional("data");
item.getEntries().addAll(Arrays.asList("a", "b", "c"));
id = (Long) s.save(item);
s.flush();
s.getTransaction().commit();
s = openSession();
s.beginTransaction();
item = (ItemTransactional) s.get(ItemTransactional.class, id);
assertThat(item.getEntries()).containsExactly("a", "b", "c");
s.getTransaction().commit();
s.close();
Assert.assertEquals(1, stats.getSecondLevelCacheStatistics("item_entries").getPutCount());
s = openSession();
s.beginTransaction();
item = (ItemTransactional) s.get(ItemTransactional.class, id);
assertThat(item.getEntries()).containsExactly("a", "b", "c");
s.delete(item);
s.getTransaction().commit();
s.close();
Assert.assertEquals(1, stats.getSecondLevelCacheStatistics("item_entries").getHitCount());
}
@Test
public void testNaturalId() {
Statistics stats = sessionFactory().getStatistics();
Session s = openSession();
s.beginTransaction();
ItemTransactional item = new ItemTransactional("data");
item.setNid("123");
s.save(item);
s.flush();
s.getTransaction().commit();
Assert.assertEquals(1, stats.getSecondLevelCacheStatistics("item").getPutCount());
Assert.assertEquals(1, stats.getNaturalIdCacheStatistics("item##NaturalId").getPutCount());
s = openSession();
s.beginTransaction();
item = (ItemTransactional) s.bySimpleNaturalId(ItemTransactional.class).load("123");
assertThat(item).isNotNull();
s.delete(item);
s.getTransaction().commit();
s.close();
Assert.assertEquals(1, stats.getSecondLevelCacheStatistics("item").getHitCount());
Assert.assertEquals(1, stats.getNaturalIdCacheStatistics("item##NaturalId").getHitCount());
sessionFactory().getStatistics().logSummary();
}
@Test
public void testUpdateWithRefreshThenRollback() {
Statistics stats = sessionFactory().getStatistics();
Long id = null;
Session s = openSession();
s.beginTransaction();
ItemTransactional item = new ItemTransactional( "data" );
id = (Long) s.save( item );
s.flush();
s.getTransaction().commit();
Assert.assertEquals(1, stats.getSecondLevelCacheStatistics("item").getPutCount());
s = openSession();
s.beginTransaction();
item = (ItemTransactional) s.get(ItemTransactional.class, id);
item.setName("newdata");
s.update(item);
s.flush();
s.refresh(item);
s.getTransaction().rollback();
s.clear();
s.close();
Assert.assertEquals(1, stats.getSecondLevelCacheStatistics("item").getHitCount());
}
}

@ -1,8 +0,0 @@
{
"singleServerConfig":{
"address": "redis://127.0.0.1:6379"
},
"codec":{
"class":"org.redisson.codec.FstCodec"
}
}

@ -1,8 +0,0 @@
{
"singleServerConfig":{
"address": "redis://127.0.0.1:6379"
},
"codec":{
"class":"org.redisson.codec.FstCodec"
}
}

@ -14,8 +14,6 @@
<name>Redisson/Spring Data Redis integration</name>
<modules>
<module>redisson-spring-data-16</module>
<module>redisson-spring-data-17</module>
<module>redisson-spring-data-18</module>
<module>redisson-spring-data-20</module>
<module>redisson-spring-data-21</module>

@ -1,76 +0,0 @@
<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.redisson</groupId>
<artifactId>redisson-spring-data</artifactId>
<version>3.11.7-SNAPSHOT</version>
<relativePath>../</relativePath>
</parent>
<artifactId>redisson-spring-data-16</artifactId>
<packaging>jar</packaging>
<name>Redisson/Spring Data Redis v1.6.x integration</name>
<dependencies>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-redis</artifactId>
<version>1.6.6.RELEASE</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<version>3.1.2</version>
<configuration>
<archive>
<manifestEntries>
<Build-Time>${maven.build.timestamp}</Build-Time>
<Automatic-Module-Name>redisson.spring.data16</Automatic-Module-Name>
</manifestEntries>
</archive>
</configuration>
</plugin>
<plugin>
<groupId>com.mycila</groupId>
<artifactId>license-maven-plugin</artifactId>
<version>3.0</version>
<configuration>
<basedir>${basedir}</basedir>
<header>${basedir}/../../header.txt</header>
<quiet>false</quiet>
<failIfMissing>true</failIfMissing>
<aggregate>false</aggregate>
<includes>
<include>src/main/java/org/redisson/</include>
</includes>
<excludes>
<exclude>target/**</exclude>
</excludes>
<useDefaultExcludes>true</useDefaultExcludes>
<mapping>
<java>JAVADOC_STYLE</java>
</mapping>
<strictCheck>true</strictCheck>
<useDefaultMapping>true</useDefaultMapping>
<encoding>UTF-8</encoding>
</configuration>
<executions>
<execution>
<goals>
<goal>check</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

@ -1,37 +0,0 @@
/**
* Copyright (c) 2013-2019 Nikita Koksharov
*
* 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.
*/
package org.redisson.spring.data.connection;
import org.redisson.client.protocol.convertor.Convertor;
import io.netty.util.CharsetUtil;
/**
*
* @author Nikita Koksharov
*
*/
public class BinaryConvertor implements Convertor<Object> {
@Override
public Object convert(Object obj) {
if (obj instanceof String) {
return ((String) obj).getBytes(CharsetUtil.UTF_8);
}
return obj;
}
}

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save