java - 有没有办法让 eclipselink/JPA 使用 redis 来保存和检索持久性单元级 (L2) 缓存?

标签 java jpa redis eclipselink redisson

我正在设置一个集群环境,我希望我的 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 )。

问候,

关于java - 有没有办法让 eclipselink/JPA 使用 redis 来保存和检索持久性单元级 (L2) 缓存?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57853099/

相关文章:

java - 如何使用jpa项目eclipse在实体类中生成唯一约束

java - 从 JPA 注释的实体类自动生成数据模式

redis - 在 debian/ubuntu 启动时启动 redis-server

java - System.out.printf() 用于 float 数据类型

java - 用于检索多列的 Spring Data 方法名称

database - hibernate :OnDelete 与 cascade=CascadeType.REMOVE

amazon-web-services - 带一个 float 的 AWS 存储

javascript - 在第一场比赛中停止 Redis hget

java - Primefaces 选择列表转换器

java - 恢复丢失的类型同时避免 'unchecked cast' 警告