I'm setting up a cluster environment and I want my JPA's second level cache to be replicated throughout the cluster's nodes. I'm using eclipselink as JPA provider and redis for cache management.
There is no official or community project that support it.
However, you can implement your own CacheInterceptor.
Eg.
import org.eclipse.persistence.descriptors.ClassDescriptor;
import org.eclipse.persistence.internal.identitymaps.CacheKey;
import org.eclipse.persistence.internal.identitymaps.IdentityMap;
import org.eclipse.persistence.internal.sessions.AbstractSession;
import org.eclipse.persistence.sessions.interceptors.CacheInterceptor;
import org.eclipse.persistence.sessions.interceptors.CacheKeyInterceptor;
import java.util.Map;
public class MyRedisCacheInterceptor extends CacheInterceptor {
private final MyCacheProvider cacheSupport;
private final String cacheName;
public DefaultCacheInterceptor(IdentityMap targetIdentityMap, AbstractSession interceptedSession,
String cacheName, DefaultCacheSupport cacheSupport) {
super(targetIdentityMap, interceptedSession);
this.cacheSupport = cacheSupport;
this.cacheName = cacheName;
}
@Override
public Object clone() {
return null;
}
@Override
protected CacheKeyInterceptor createCacheKeyInterceptor(CacheKey wrappedCacheKey) {
final long longKey = (long) wrappedCacheKey.getKey();
CacheKeyInterceptor newKey = new CacheKeyInterceptor(wrappedCacheKey) {
@Override
public Object getObject() {
return cacheSupport.getOrCreateCache(cacheName).get(longKey);
}
@Override
public void setObject(Object object) {
cacheSupport.getOrCreateCache(cacheName).put(longKey, object);
}
};
return newKey;
}
@Override
public boolean containsKey(Object primaryKey) {
return cacheSupport.getOrCreateCache(cacheName).containsKey(primaryKey);
}
@Override
public Map<Object, Object> getAllFromIdentityMapWithEntityPK(Object[] pkList, ClassDescriptor descriptor, AbstractSession session) {
return null;
}
@Override
public Map<Object, CacheKey> getAllCacheKeysFromIdentityMapWithEntityPK(Object[] pkList, ClassDescriptor descriptor, AbstractSession session) {
return null;
}
@Override
public void release() {
}
}
You can take a look to this project that uses Apache Ignite, replace it with Redis and try. sample project
Cache Interceptor Impl: Sample cache interceptor impl
Ignite Cache Interceptor: Sample Ignite cache interceptor project
Other sample project with Hazelcast: Sample Hazelcast cache interceptor project
In short, If you need to use Redis as a second level cache you need to implement your own customization or maybe Hibernate is your best choice. It has a redisson-hibernate cache provider that you can plug (redisson-hibernate).
Regards,