最近写集成测试来测试一个实体+集合缓存的程序,单独执行没有问题,一旦多个测试用例一起执行会造成从第二个出现可能加载到第一个测试用例集合的内容。
测试用例:
第一个测试用例:
1、通过加载sql装载:
User#1
farms
Farm#1
Farm#2
2、接下来执行没有问题;
第二个测试用例:
1、通过加载sql装载:
User#1
farms
Farm#3
Farm#4
Farm#5
2、接着调用jpa的:
entityManager.getEntityManagerFactory().getCache().evictAll(); 清空二级缓存;
entityManager.clear(); 清空一级缓存
3、接下来会发现:
User#1 得到的farms还是 Farm#1、Farm#2 而没有新装载的,也就是得到第一个测试用例的。
这是为什么呢?
因为jpa没有集合缓存的概念,而是hibernate里特有的,因此entityManager.getEntityManagerFactory().getCache().evictAll(); 只清空实体缓存,而实体对应的集合缓存还是存在的,因此不会查数据库获取最新的。。。
jpa Cache相关的概念可参考http://en.wikibooks.org/wiki/Java_Persistence/Caching
hibernate jpa cache的实现代码如下(org.hibernate.ejb.EntityManagerFactoryImpl.JPACache):
public void evictAll() { sessionFactory.getCache().evictEntityRegions(); // TODO : if we want to allow an optional clearing of all cache data, the additional calls would be: //sessionFactory.getCache().evictCollectionRegions(); //sessionFactory.getCache().evictQueryRegions(); }
那就找能删除集合缓存的api吧,entityManager.getEntityManagerFactory().getCache()中是没有的。。咋办? 此时只能获取hibernate的SessionFactory 然后清空二级缓存了。
因此写了个工具类:
/** * Copyright (c) 2005-2012 https://github.com/zhangkaitao * * Licensed under the Apache License, Version 2.0 (the "License"); */ package com.sishuok.es.common.repository.hibernate; import org.hibernate.Cache; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.ejb.HibernateEntityManagerFactory; import javax.persistence.EntityManager; import javax.persistence.EntityManagerFactory; /** * 根据 jpa api 获取hibernate相关api * <p>User: Zhang Kaitao * <p>Date: 13-5-23 下午6:24 * <p>Version: 1.0 */ public class HibernateUtils { /** * 根据jpa EntityManager 获取 hibernate Session API * @param em * @return */ public static Session getSession(EntityManager em) { return (Session) em.getDelegate(); } /** * 根据jpa EntityManager 获取 hibernate SessionFactory API * @see #getSessionFactory(javax.persistence.EntityManagerFactory) * @param em * @return */ public static SessionFactory getSessionFactory(EntityManager em) { return getSessionFactory(em.getEntityManagerFactory()); } /** * 根据jpa EntityManagerFactory 获取 hibernate SessionFactory API * @param emf * @return */ public static SessionFactory getSessionFactory(EntityManagerFactory emf) { return ((HibernateEntityManagerFactory)emf).getSessionFactory(); } /** * 根据 jpa EntityManager 获取hibernate Cache API * @see #getCache(javax.persistence.EntityManagerFactory) * @param em * @return */ public static Cache getCache(EntityManager em) { return getCache(em.getEntityManagerFactory()); } /** * 根据jpa EntityManagerFactory 获取 hibernate Cache API * @param emf * @return */ public static Cache getCache(EntityManagerFactory emf) { return getSessionFactory(emf).getCache(); } /** * 清空一级缓存 * @param em */ public static void clearLevel1Cache(EntityManager em) { em.clear(); } /** * 根据jpa EntityManager 清空二级缓存 * @see #clearLevel2Cache(javax.persistence.EntityManagerFactory) * @param em */ public static void clearLevel2Cache(EntityManager em) { clearLevel2Cache(em.getEntityManagerFactory()); } /** * 根据jpa EntityManagerFactory 清空二级缓存 包括: * 1、实体缓存 * 2、集合缓存 * 3、查询缓存 * 注意: * jpa Cache api 只能evict 实体缓存,其他缓存是删不掉的。。。 * @see org.hibernate.ejb.EntityManagerFactoryImpl.JPACache#evictAll() * * @param emf */ public static void clearLevel2Cache(EntityManagerFactory emf) { Cache cache = HibernateUtils.getCache(emf); cache.evictEntityRegions(); cache.evictCollectionRegions(); cache.evictDefaultQueryRegion(); cache.evictQueryRegions(); cache.evictNaturalIdRegions(); } }
此时可以调用clearLevel2Cache清空二级缓存的所有内容。
相关阅读:
相关推荐
在本文中,我们将深入探讨如何在Spring Boot 2.1.4.RELEASE项目中结合JPA(Java Persistence API)和Hibernate实现Redis作为二级缓存。首先,我们需要理解这些技术的基本概念。 Spring Boot 是一个用于简化Spring...
在本配置中,Hibernate版本为5.1.3,支持JPA规范,提供了二级缓存功能,提高了数据访问性能。 4. **二级缓存(Ehcache)**: Ehcache是Hibernate的一个可选二级缓存插件,用于存储数据库查询结果,减少对数据库的...
- **二级缓存**: JPA允许配置二级缓存,以提高数据访问速度。 **8. 事务管理** - JPA支持声明式和编程式事务管理,可以配合Spring框架进行事务控制。 **9. 数据库迁移** - JPA结合Hibernate的Hibernate Tools,...
- **Hibernate**:支持一级缓存和二级缓存,可以有效地提高性能。 - **OpenJPA/JPA**:同样支持缓存机制,但在实现细节上可能有所不同。 #### 四、迁移过程中的注意事项 1. **代码适应性调整**:迁移过程中需要...
它不仅支持JPA的标准特性,还提供了额外的工具和配置选项,例如二级缓存、事件监听器、CGLIB和ASM动态代理等,使得开发者可以更高效地处理数据库操作。 **JPA的核心概念** 1. **实体(Entity)**:在JPA中,实体是...
- 使用`@Cacheable`和二级缓存提高数据读取速度。 - 使用`@QueryHints`控制查询性能,如分页查询。 - 注意避免N+1查询问题,通过JOIN查询优化。 ### 9. 测试 编写测试用例,使用`@DataJpaTest`或`@SpringBootTest`...
Spring和OpenJPA的集成使得开发更加便利,但也有几点需要注意: - **事务边界**:合理设置事务边界,确保业务逻辑的完整性和一致性。 - **性能优化**:合理使用OpenJPA的缓存策略,避免过多的数据库查询。 - **懒...
为了进一步提升效率,Hibernate提供了一级缓存和二级缓存机制,一级缓存是每个Session内的缓存,二级缓存则可以在多个Session之间共享,有效减少了数据库的访问次数。 总结来说,"Spring+SpringMVC+SpringDataJPA+...
二级缓存允许频繁访问的数据在内存中被缓存,减少了对数据库的直接访问,从而提升了应用程序的性能。 最后,"jpaweb"可能指的是项目的Web层,它展示了如何将这些框架整合到一个Web应用中,可能使用了如Spring MVC...
5. **第二级缓存**:支持跨会话的缓存策略,提高了应用程序的性能和响应速度。 6. **复合主键**:允许实体使用多个属性作为其主键,增强了模型的表达能力。 7. **关联管理的优化**:包括延迟加载的改进,使得关联...
对于复杂的应用场景,可能需要配置更多的Spring和Hibernate特性,例如二级缓存、查询缓存、拦截器等。同时,结合Spring MVC或Spring Boot等Web框架,可以构建出完整的、高度可扩展的企业级应用。 总之,Spring与JPA...
6. **缓存机制**:支持一级缓存(实体管理器内的缓存)和二级缓存(全局共享),提高性能。 7. **事务管理**:与Spring等框架集成,支持声明式和编程式事务控制。 **整合Spring MVC与OpenJPA** 在Spring MVC应用中...
5. **性能优化**:可能包含了一些性能调优的技巧,比如批处理操作、二级缓存的使用等。 6. **生命周期回调**:理解实体的生命周期方法(如@PrePersist、@PostLoad等),以及如何在这些方法中添加业务逻辑。 通过...
Hibernate不仅实现了JPA规范,还提供了一些额外的功能,如二级缓存和查询语言HQL。在Spring+Jersey+JPA+Hibernate的组合中,Hibernate作为JPA的具体实现,负责与MySQL数据库之间的交互。 MySQL是一种广泛使用的开源...
3. **Hibernate 3.6.1**: Hibernate是JPA的增强版,提供了许多额外的功能,如二级缓存、实体关系映射(ORM)、事务管理等。在这个投票系统中,Hibernate将用于定义实体类,通过注解指定数据库表结构,并处理数据库...
Hibernate不仅实现了JPA规范,还提供了许多额外的功能,如第二级缓存、查询语言(HQL)以及对复杂对象关系的深度支持。 在JPA应用中,我们需要了解以下几个关键概念: 1. **实体(Entity)**:在JPA中,实体是与...
- **二级缓存**:Hibernate的第二级缓存可以缓存整个实体,提高性能,但需谨慎使用,以防数据一致性问题。 - **多态(Polymorphism)**:JPA支持继承和多态,允许不同类型的实体共享相同的表。 通过上述知识点的...
`<properties>`标签内设置了一些Hibernate特定的属性,例如禁用二级缓存和更新ID生成器映射策略。 接下来,创建一个表示持久化实体的Java类。使用`@Entity`注解标记此类为JPA实体,同时为每个需要持久化的字段添加...
例如,可以通过`@Cacheable`注解启用二级缓存,提高查询效率。 9. **集成测试** 在Spring测试框架中,可以使用`@DataJpaTest`和`@AutoConfigureTestDatabase`注解进行JPA的集成测试,确保代码的正确性。 总结,...
而Hibernate4是JPA的一个流行实现,它提供了更丰富的功能,如第二级缓存、事务管理和事件监听器。 在Eclipse中创建Dynamic Web Project是Web应用开发的常见起点。这样的项目结构允许开发者构建符合Java Servlet规范...