You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring+Hibernate集群缓存PoC问题:数据库对象未存入BigMemory Max

解决Ehcache + Terracotta + JPA事务缓存不生效的问题

我看了你遇到的问题——用JPA结合Ehcache+Terracotta(BigMemory Max)做事务缓存PoC,手动调用bigMemory.put()能成功把对象存入缓存,但通过JPA操作后Terracotta控制台始终显示缓存对象数为0。这大概率是JPA与Ehcache的集成配置没到位,或者事务缓存的触发逻辑没走对。下面给你几个具体的排查和解决方向:


1. 先把JPA二级缓存的核心配置补上

Hibernate默认是关闭二级缓存的,你现在的配置里完全没开启这个功能,自然不会自动把实体存入Ehcache:

  • 在application.properties中添加Hibernate缓存开启配置:
    # 开启二级缓存
    spring.jpa.properties.hibernate.cache.use_second_level_cache=true
    # 指定用Ehcache作为缓存区域工厂
    spring.jpa.properties.hibernate.cache.region.factory_class=org.hibernate.cache.ehcache.EhCacheRegionFactory
    # 可选:如果需要缓存findAll这类查询结果,开启查询缓存
    spring.jpa.properties.hibernate.cache.use_query_cache=true
    
  • 给你的Note实体类加上缓存注解,告诉Hibernate要把这个实体的实例存入缓存:
    @Entity
    @Table(name = "notes")
    @Cacheable
    @Cache(usage = CacheConcurrencyStrategy.TRANSACTIONAL, region = "com.example.pocehcache.model.Note")
    public class Note implements Serializable {
        // ... 你的现有代码
    }
    
    这里的region值必须和你ehcache.xml里定义的缓存name完全一致,这样Hibernate才会把实体放到你配置的分布式缓存中。

2. 确保Atomikos与Ehcache的XA事务集成正确

你开启了Ehcache的transactionalMode="xa",要保证Spring的事务管理和Atomikos的XA事务能正确联动:

  • 检查是否引入了对应版本的ehcache-transactions依赖,这是Ehcache支持XA事务的必要jar包。
  • 显式配置Atomikos的事务管理器(Spring默认的事务管理器不支持XA),替换掉默认的事务管理逻辑:
    @Configuration
    public class AtomikosConfig {
        @Bean
        public PlatformTransactionManager transactionManager() throws SystemException {
            JtaTransactionManager transactionManager = new JtaTransactionManager();
            transactionManager.setTransactionManager(atomikosTransactionManager());
            transactionManager.setUserTransaction(atomikosUserTransaction());
            return transactionManager;
        }
    
        @Bean
        public UserTransaction atomikosUserTransaction() throws SystemException {
            UserTransactionImp userTransactionImp = new UserTransactionImp();
            userTransactionImp.setTransactionTimeout(300);
            return userTransactionImp;
        }
    
        @Bean(initMethod = "init", destroyMethod = "close")
        public TransactionManager atomikosTransactionManager() {
            UserTransactionManager userTransactionManager = new UserTransactionManager();
            userTransactionManager.setForceShutdown(false);
            return userTransactionManager;
        }
    }
    
    这样Spring的@Transactional注解才会使用Atomikos的XA事务管理器,保证缓存操作和数据库操作的事务一致性。

3. 验证缓存触发时机与查询缓存配置

  • JPA的二级缓存是在事务提交后才会写入的,所以调用完createNote或者getAllNotes后,不要立刻去看Terracotta控制台,等几秒让事务提交完成再检查。
  • 如果要缓存findAll这类批量查询的结果,需要给Repository的方法加上查询缓存注解:
    @Repository
    public interface NoteRepository extends JpaRepository<Note, Long> {
        @Override
        @QueryHints(@QueryHint(name = org.hibernate.annotations.QueryHints.CACHEABLE, value = "true"))
        List<Note> findAll();
    }
    
    否则Hibernate只会缓存单个实体对象,不会缓存查询结果集。

4. 排查日志定位问题

开启Hibernate、Ehcache和Atomikos的Debug日志,能帮你快速定位缓存是否被正确触发:
在application.properties中添加:

logging.level.org.hibernate.cache=DEBUG
logging.level.net.sf.ehcache=DEBUG
logging.level.com.atomikos=DEBUG

查看日志里是否有类似CachePut(Hibernate)或Element added to cache(Ehcache)的日志:

  • 如果没有这类日志:说明缓存逻辑根本没触发,回到第一步检查JPA缓存配置。
  • 如果有日志但Terracotta控制台没显示:检查Terracotta服务器连接是否正常(日志里会有连接成功的提示),或者缓存region名称是否匹配。

内容的提问来源于stack exchange,提问作者snesh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 03:30:35