简体   繁体   中英

EHCache with Spring 3.1 and Hibernate 4 annotations - making it works

I'm trying to get EHCache working within my app. First thing I did was adding maven dependency:

pom.xml

    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-ehcache</artifactId>
        <version>${hibernate-version}</version>
    </dependency>

So far so good, now within my application root-context.xml (SessionFactory is defiend in roout because of OpenSessionInView filter) I added MBean for Hibernate statistics from jConsole and full definition of my sessionFactory:

root-context.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">

<!-- Root Context: defines shared resources visible to all other web components -->
<bean id="jmxExporter"
      class="org.springframework.jmx.export.MBeanExporter">
    <property name="beans">
        <map>
            <entry key="Hibernate:type=statistics">
                <ref local="statisticsBean"/>
            </entry>
        </map>
    </property>
</bean>
<bean id="statisticsBean" class="org.hibernate.jmx.StatisticsService">
    <property name="statisticsEnabled" value="true"/>
    <property name="sessionFactory" ref="sessionFactory"/>
</bean>

<bean id="namingStrategy" class="com.execon.OracleNamingStrategy"/>

<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
    <property name="driverClass" value="oracle.jdbc.OracleDriver"/>
    <property name="jdbcUrl" value="jdbc:oracle:thin:@127.0.0.1:1521:orcl"/>
    <property name="user" value="xxx"/>
    <property name="password" value="xxx"/>
    <property name="maxPoolSize" value="10"/>
    <property name="maxStatements" value="0"/>
    <property name="minPoolSize" value="5"/>
</bean>

<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
    <property name="namingStrategy" ref="namingStrategy"/>
    <property name="dataSource" ref="dataSource"/>
    <property name="configLocation" value="classpath:hibernate.cfg.xml"/>
    <property name="packagesToScan" value="com.execon.models"/>
</bean>
</beans>

Time to define hibernate.cfg.xml and ehcache file, so here they are:

hibernate.cfg.xml

<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
    "-//Hibernate/Hibernate Configuration DTD//EN"
    "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">

<hibernate-configuration>
<session-factory>
    <property name="show_sql">true</property>
    <property name="format_sql">true</property>
    <property name="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.EhCacheRegionFactory</property>
    <property name="hibernate.cache.use_query_cache">true</property>
    <property name="hibernate.cache.use_second_level_cache">true</property>
    <property name="hibernate.cache.provider_configuration_file_resource_path">ehcache.xml</property>
    <property name="hibernate.generate_statistics">true</property>
</session-factory>
</hibernate-configuration>

ehcache.xml

<?xml version="1.0" encoding="UTF-8"?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd">

<diskStore path="java.io.tmpdir"/>
<defaultCache
        eternal="false"
        maxElementsInMemory="1000"
        maxElementsOnDisk="10000"
        overflowToDisk="true"
        diskPersistent="true"
        timeToLiveSeconds="300"
        />
</ehcache>

Everything is working great, so now its time to define some Service to test cache, so I did:

@Service
@Scope(value = "prototype", proxyMode = ScopedProxyMode.TARGET_CLASS)
@Transactional(readOnly = true)
public class MyService
{
    @Autowired
    private SessionFactory sessionFactory;

    @SuppressWarnings("unchecked")
    @Cache(usage = CacheConcurrencyStrategy.TRANSACTIONAL)
    public List<SettlementModelGroup> getModelGroups()
    {
        List<SettlementModelGroup> list = new ArrayList<SettlementModelGroup>();
        Session session = sessionFactory.getCurrentSession();
        Query query = session.createQuery( "from SettlementModelGroup" );

        list.addAll( query.list() );

        return list;
    }
}

As you can see, this basic method alwas returns me same list. So I'm checking hibernate statistics and:

secondLevelCacheHitCount 0
secondLevelCacheMissCount 0
secondLevelCachePutCount 0

Rest of the statistics on screen:

图 Link if too small: http://s11.postimage.org/yfg9h6m83/image.jpg

So whats wrong, did I miss something (obvious)? Or am I going completly wrong way?

EDIT

SettlementModelGroup Entity (tried also CacheConcurrencyStrategy.READ_WRITE)

@Entity
@Table(name = "MODEL_GROUP")
@Cache(usage = CacheConcurrencyStrategy.TRANSACTIONAL)
public class SettlementModelGroup implements Serializable
{
@Id
@GeneratedValue(generator = "MODEL_GROUP_SEQ", strategy = GenerationType.SEQUENCE)
@SequenceGenerator(name = "MODEL_GROUP_SEQ", sequenceName = "SEQ_MODEL_GROUP_MODEL_GROUP_ID")
@Column(name = "MODEL_GROUP_ID", nullable = false)
private Integer modelId;

@Column(name = "NAME", nullable = false)
private String modelGroupName;

@Column(name = "DESCRIPTION", nullable = false)
private String modelGroupDescription;

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "MODEL_GROUP_TYPE_ID", nullable = false)
private SettlementModelGroupType settlementModelGroupType;

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "PERIOD_TYPE_ID", nullable = false)
private PeriodType periodType;

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "DOMAIN_ID")
private Domain domain;

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "OWNER_ID", nullable = false)
private User user;

@OneToMany(fetch = FetchType.LAZY, mappedBy = "modelId")
@Cascade(CascadeType.ALL)
private List<SettlementModel> settlementModels;

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "STATUS_ID")
private Status status;

//getters and setters here
}

Put @Cache(usage = CacheConcurrencyStrategy.TRANSACTIONAL) on SettlementModelGroup (your domain entity) not the service method.

Also see this link . Depending on your version of EhCache (2.4.3.?) you might have to use CacheConcurrencyStrategy.READ_WRITE.

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