使用版本;
<spring.version>3.2.8.RELEASE</spring.version>
<hibernate.version>4.2.11.Final</hibernate.version>
hibernate 配置;
...
<bean id="jpaAdapter"
class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"
p:database="${jpa.database}" p:showSql="${jpa.showSql}"/>
<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="hibernateProperties">
<props>
<prop key="hibernate.hbm2ddl.auto">auto</prop>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQL5InnoDBDialect</prop>
<prop key="hibernate.connection.autocommit">true</prop>
<prop key="hibernate.cache.use_second_level_cache">true</prop>
<prop key="hibernate.cache.use_query_cache">true</prop>
<prop key="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.EhCacheRegionFactory</prop>
<!--useful for debugging-->
<prop key="hibernate.generate_statistics">true</prop>
</props>
</property>
<property name="packagesToScan" value="info.hevi.learn.spring3hibernate4ehcache"/>
</bean>
<bean id="transactionManager"
class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
...
ehcache配置(ehcache.xml);
<cache name="countryCache"
maxElementsInMemory="300"
eternal="true"
overflowToDisk="false"
timeToIdleSeconds="12000"
timeToLiveSeconds="12000"
diskPersistent="false"
diskExpiryThreadIntervalSeconds="120"
memoryStoreEvictionPolicy="LRU" />
<cache name="info.hevi.learn.spring3hibernate4ehcache.domain.Country"
maxElementsInMemory="300"
eternal="true"
overflowToDisk="false"
timeToIdleSeconds="12000"
timeToLiveSeconds="12000"
diskPersistent="false"
diskExpiryThreadIntervalSeconds="120"
memoryStoreEvictionPolicy="LRU" />
领域类;
public class Language implements IEntity {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@Column(nullable = false, unique = true)
private String name;
...
}
和
@Entity
@Table(name = "countries")
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
@NamedQueries({
@NamedQuery(name="Country.findLanguagesByCountryId",query="select language from Country country inner join country.languages language where country.id=:cid")
})
public class Country implements IEntity {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@Column
private String name;
@Column
private Integer population;
@Column(updatable = false, insertable = false)
@Temporal(TemporalType.TIMESTAMP)
private Calendar creation;
@ManyToMany(targetEntity = Language.class, fetch = FetchType.EAGER)
@JoinTable(name = "country_language", joinColumns = {@JoinColumn(name = "cid")}, inverseJoinColumns = {@JoinColumn(name = "lid")})
private Set<Language> languages;
...
}
和服务等级;
@Service(value = "countryService")
public class CountryService extends AbstractBasicService<Country, Long, ICountryDao> implements ICountryService {
...
@Override
@Cacheable(value = "countryCache")
@Transactional
public List<Country> getAll() {
return super.getAll();
}
...
}
和测试代码;
@Test
public void testCache() {
countryService.getAll();
countryService.getAll();
countryService.getAll();
}
最后是静力学;
07-18-2014 02:26:42,991 PM INFO StatisticalLoggingSessionEventListener:275 - Session Metrics {
57541 nanoseconds spent acquiring 1 JDBC connections;
0 nanoseconds spent releasing 0 JDBC connections;
834336 nanoseconds spent preparing 1 JDBC statements;
1394341 nanoseconds spent executing 1 JDBC statements;
0 nanoseconds spent executing 0 JDBC batches;
317686 nanoseconds spent performing 7 L2C puts;
0 nanoseconds spent performing 0 L2C hits;
0 nanoseconds spent performing 0 L2C misses;
655636 nanoseconds spent executing 1 flushes (flushing a total of 11 entities and 7 collections);
109408 nanoseconds spent executing 1 partial-flushes (flushing a total of 0 entities and 0 collections)
}
07-18-2014 02:26:43,003 PM INFO StatisticalLoggingSessionEventListener:275 - Session Metrics {
31202 nanoseconds spent acquiring 1 JDBC connections;
0 nanoseconds spent releasing 0 JDBC connections;
351321 nanoseconds spent preparing 1 JDBC statements;
1095294 nanoseconds spent executing 1 JDBC statements;
0 nanoseconds spent executing 0 JDBC batches;
281218 nanoseconds spent performing 7 L2C puts;
0 nanoseconds spent performing 0 L2C hits;
0 nanoseconds spent performing 0 L2C misses;
579456 nanoseconds spent executing 1 flushes (flushing a total of 11 entities and 7 collections);
11346 nanoseconds spent executing 1 partial-flushes (flushing a total of 0 entities and 0 collections)
}
07-18-2014 02:26:43,015 PM INFO StatisticalLoggingSessionEventListener:275 - Session Metrics {
23502 nanoseconds spent acquiring 1 JDBC connections;
0 nanoseconds spent releasing 0 JDBC connections;
366313 nanoseconds spent preparing 1 JDBC statements;
695348 nanoseconds spent executing 1 JDBC statements;
0 nanoseconds spent executing 0 JDBC batches;
274329 nanoseconds spent performing 7 L2C puts;
0 nanoseconds spent performing 0 L2C hits;
0 nanoseconds spent performing 0 L2C misses;
816100 nanoseconds spent executing 1 flushes (flushing a total of 11 entities and 7 collections);
8509 nanoseconds spent executing 1 partial-flushes (flushing a total of 0 entities and 0 collections)
}
如您所见,它永远不会命中缓存,而是一直在缓存!我还调试了服务功能,它实际上执行了如果它真的是缓存则不会发生的功能。怎么了?我是否错过了 javar arg 或犯了语义错误?
最佳答案
尝试删除:
<prop key="hibernate.connection.autocommit">true</prop>
从以下方面收集统计数据:
SessionFactory.getStatistics().getSecondLevelCacheStatistics()
尝试使用
通过 id 获取实体- session.get 或 session.load:
- entityManager.find 或 entityManager.getReference
实体加载进入二级缓存,然后二级缓存仅在没有加载此类实体时才命中数据库
对于像
这样的方法countryService.getAll();
这也意味着查询缓存,您需要为每个特定查询显式激活查询缓存:
query.setCacheable(true);
关于java - 二级缓存永不命中using、spring3、hibernate4、ehcache?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24824052/