简体   繁体   中英

Second Level Cache never hits using, spring3, hibernate4, ehcache?

using versions;

    <spring.version>3.2.8.RELEASE</spring.version>
    <hibernate.version>4.2.11.Final</hibernate.version>

hibernate configuration;

...
<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 configuration (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"  />

domain classes;

public class Language implements IEntity {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    @Column(nullable = false, unique = true)
    private String name;
    ...
}

and

@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;
    ...
}

and service class;

@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();
    }
...
}

and test code;

    @Test
public void testCache() {

    countryService.getAll();
    countryService.getAll();
    countryService.getAll();

}

and lastly the statictics;

    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)
}

As you can see it never hits the cache, all the time puts! I also debuged into the service function, it actually executes the function which is not suppose to happen if it is really caches. What's wrong? Do I miss an javar arg or make a semantic mistake?

  1. Try removing:

     <prop key="hibernate.connection.autocommit">true</prop> 
  2. Collect the statistics from:

     SessionFactory.getStatistics().getSecondLevelCacheStatistics() 
  3. Try getting an entity by it's id using

    • session.get or session.load:
    • entityManager.find or entityManager.getReference

    The entity loading goes to 2st level cache, then 2nd level cache only to hit the db if there isn't such entity already loaded

  4. For methods like

     countryService.getAll(); 

    that imply the query cache too, you need to explicitly activate the query cache for each particular query:

     query.setCacheable(true); 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM