Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/369.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 有没有办法让eclipselink/JPA使用redis来保存和检索peristence单位级(L2)缓存?_Java_Jpa_Redis_Eclipselink_Redisson - Fatal编程技术网

Java 有没有办法让eclipselink/JPA使用redis来保存和检索peristence单位级(L2)缓存?

Java 有没有办法让eclipselink/JPA使用redis来保存和检索peristence单位级(L2)缓存?,java,jpa,redis,eclipselink,redisson,Java,Jpa,Redis,Eclipselink,Redisson,我正在设置一个集群环境,我希望我的JPA的二级缓存能够在集群的节点中复制。我使用eclipselink作为JPA提供商,使用redis进行缓存管理。没有官方或社区项目支持它 但是,您可以实现自己的 例如 import org.eclipse.persistence.descriptors.ClassDescriptor; 导入org.eclipse.persistence.internal.identitymap.CacheKey; 导入org.eclipse.persistence.inter

我正在设置一个集群环境,我希望我的JPA的二级缓存能够在集群的节点中复制。我使用eclipselink作为JPA提供商,使用redis进行缓存管理。

没有官方或社区项目支持它

但是,您可以实现自己的

例如

import org.eclipse.persistence.descriptors.ClassDescriptor;
导入org.eclipse.persistence.internal.identitymap.CacheKey;
导入org.eclipse.persistence.internal.IdentityMap.IdentityMap;
导入org.eclipse.persistence.internal.sessions.AbstractSession;
导入org.eclipse.persistence.sessions.interceptors.CacheInterceptor;
导入org.eclipse.persistence.sessions.interceptors.CacheKeyInterceptor;
导入java.util.Map;
公共类MyRedisCacheInterceptor扩展了CacheInterceptor{
私有最终MyCacheProvider缓存支持;
私有最终字符串缓存名;
public DefaultCacheInterceptor(IdentityMap targetIdentityMap,AbstractSession interceptedSession,
字符串cacheName、DefaultCacheSupport(缓存支持){
super(targetIdentityMap,interceptedSession);
this.cacheSupport=cacheSupport;
this.cacheName=cacheName;
}
@凌驾
公共对象克隆(){
返回null;
}
@凌驾
受保护的CacheKeyInterceptor createCacheKeyInterceptor(CacheKey wrappedCacheKey){
final long longKey=(long)wrappedCacheKey.getKey();
CacheKeyInterceptor newKey=新CacheKeyInterceptor(wrappedCacheKey){
@凌驾
公共对象getObject(){
返回cacheSupport.getOrCreateCache(cacheName).get(longKey);
}
@凌驾
公共void集合对象(对象){
getOrCreateCache(cacheName).put(longKey,object);
}
};
返回newKey;
}
@凌驾
公共布尔containsKey(对象主键){
返回cacheSupport.getOrCreateCache(cacheName).containsKey(primaryKey);
}
@凌驾
公共映射getAllFromIdentityMapWithEntityPK(对象[]pkList,类描述符描述符,抽象会话){
返回null;
}
@凌驾
公共映射getAllCacheKeysFromIdentityMapWithEntityPK(对象[]pkList,类描述符描述符,抽象会话){
返回null;
}
@凌驾
公开无效释放(){
}
}
您可以看看这个使用ApacheIgnite的项目,用Redis替换它,然后再试一次。

缓存侦听器Impl:

Ignite缓存拦截器:

Hazelcast的其他样本项目:

简而言之,如果您需要使用Redis作为二级缓存,那么您需要实现自己的定制,或者Hibernate是您的最佳选择。它有一个redisson hibernate缓存提供程序,您可以将其插入()


在考虑远程二级缓存的正确性和性能方面时,

可能会有所帮助。它涵盖了Hibernate如何与二级缓存交互,我不确定它在EclipseLink中是如何工作的(我假设有很多相似之处)。这是一个有趣的想法。我的猜测正确吗?您的意图是将其用于一种二级缓存,这种缓存将在集群的节点之间共享?@Captain yes。像HibernateRedis一样,我希望使用redis在集群中的所有节点上共享eclipselink二级缓存。谢谢。它工作了,但几乎不需要做什么更改,因为在第一次从DB中检索并将
CacheKeyInterceptor
setObject
放入缓存时,将向您的bean传递一个空对象,即此时不会设置此对象的任何属性。因此,立即将其放入redis将把这个空对象放入缓存,这将是无用的。现在,作为一种解决方法,我将bean放在redis中的
updateAccess
中,在正确设置对象的属性后将调用该bean。
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() {
    }
}