有没有办法让 eclipselink/JPA 使用 redis 来保存和检索持久性单元级 (L2) 缓存?
Is there a way to make eclipselink/JPA use redis for saving and retrieving peristence-unit level (L2) cache?
我正在设置一个集群环境,我希望我的 JPA 的二级缓存在整个集群的节点中被复制。我使用 eclipselink 作为 JPA 提供程序,使用 redis 进行缓存管理。
没有官方或社区项目支持它。
但是,您可以实现自己的 CacheInterceptor。
例如
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() {
}
}
你可以看看这个使用Apache Ignite的项目,换成Redis试试。
sample project
缓存拦截器实现:Sample cache interceptor impl
点燃缓存拦截器:Sample Ignite cache interceptor project
Hazelcast 的其他示例项目:Sample Hazelcast cache interceptor project
简而言之,如果您需要使用 Redis 作为二级缓存,您需要实现自己的定制,或者 Hibernate 是您的最佳选择。它有一个可以插入的 redisson-hibernate 缓存提供程序 (redisson-hibernate)。
此致,
我正在设置一个集群环境,我希望我的 JPA 的二级缓存在整个集群的节点中被复制。我使用 eclipselink 作为 JPA 提供程序,使用 redis 进行缓存管理。
没有官方或社区项目支持它。
但是,您可以实现自己的 CacheInterceptor。
例如
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() {
}
}
你可以看看这个使用Apache Ignite的项目,换成Redis试试。 sample project
缓存拦截器实现:Sample cache interceptor impl
点燃缓存拦截器:Sample Ignite cache interceptor project
Hazelcast 的其他示例项目:Sample Hazelcast cache interceptor project
简而言之,如果您需要使用 Redis 作为二级缓存,您需要实现自己的定制,或者 Hibernate 是您的最佳选择。它有一个可以插入的 redisson-hibernate 缓存提供程序 (redisson-hibernate)。
此致,