J888
J888

Reputation: 1964

Why my 2nd level cache implementation runs into error?

I am trying to implement second-level cache on my application, but it returns following error. I am suspicious to the setCacheMode.

Hibernate.cfg.xml

 ...
  <property name="cache.provider_class">
            org.hibernate.cache.EhCacheProvider
  </property>

  <property name="hibernate.cache.use_query_cache">true</property>
 ...

Product.Java

public class Product implements Serializable {
...
    @Id
    @GeneratedValue
    @Column(name = "id")
    @Cache(usage= CacheConcurrencyStrategy.READ_ONLY)
    public long getID() {
        return ID;
    }
...
}

Model.Java

....
final Session session = HibernateUtil.getSession();
        try {
            final Transaction tx = session.beginTransaction();
            try {
                Product product = (Product) session.get(Product.class, id);
                session.setCacheMode(CacheMode.NORMAL);
                tx.commit();
                return product;
            } catch (Exception e) {
                tx.rollback();
                e.printStackTrace();
            }
        } finally {
            HibernateUtil.closeSession();
        }
.....

Error

INFO: ** Exception in SessionFactory **
SEVERE: org.hibernate.service.spi.ServiceException: Unable to create requested service [org.hibernate.engine.spi.CacheImplementor]
    at org.hibernate.service.internal.AbstractServiceRegistryImpl.createService(AbstractServiceRegistryImpl.java:186)
    at org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:150)
    at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:131)
    at org.hibernate.internal.SessionFactoryImpl.<init>(SessionFactoryImpl.java:264)
    at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1760)
    at com.my.util.HibernateUtil.configureSessionFactory(HibernateUtil.java:26)
    at com.my.util.HibernateUtil.<clinit>(HibernateUtil.java:43)
    at com.my.controller.Default.execute(Default.java:29)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:601)
    at com.opensymphony.xwork2.DefaultActionInvocation.invokeAction(DefaultActionInvocation.java:446)
    at com.opensymphony.xwork2.DefaultActionInvocation.invokeActionOnly(DefaultActionInvocation.java:285)
    at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
    at org.apache.struts2.interceptor.debugging.DebuggingInterceptor.intercept(DebuggingInterceptor.java:256)
    at 
    .....

Util

 private static SessionFactory configureSessionFactory() {
        try {
            Configuration configuration = new Configuration();
            configuration.configure();
            serviceRegistry = new 
                     ServiceRegistryBuilder()
                    .applySettings(configuration.getProperties())
                    .buildServiceRegistry();

            sessionFactory = configuration.buildSessionFactory(serviceRegistry);

            return sessionFactory;
        } catch (HibernateException e) {
            System.out.append("** Exception in SessionFactory **");
            e.printStackTrace();
        }
       return sessionFactory;
  }

Upvotes: 5

Views: 9430

Answers (3)

user3198259
user3198259

Reputation: 174

If you use hibernate version higher than 3.3, you need use this property:

<property name="hibernate.cache.region.factory_class">
     org.hibernate.cache.ehcache.SingletonEhCacheRegionFactory
</property>

and add a dependency to maven:

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

and then you use:

Product product = (Product) session.get(Product.class, id);

this will be second level cache (if session is closed), not query.

Also you need to override the buildsessionFactory. Check what methods you are using in previous versions of hibernate. Then check what the higher version is using -- that method only you need to override.

Now I override the buildsessionfactory method because I am using hibernate4.3.11-final.

Upvotes: -1

Nazgul
Nazgul

Reputation: 1902

well your hbm config is missing vital parts for second level cache usage. Please add hibernate.cache.use_second_level_cache and hibernate.cache.region.factory_class options. DO consult the hbm manual for your version of hibernate for correct class values for factory.

Upvotes: 0

Pavel Bezglasniy
Pavel Bezglasniy

Reputation: 61

If you use hibernate version higher than 3.3, you need use this properties

<property name="hibernate.cache.region.factory_class">
        org.hibernate.cache.ehcache.SingletonEhCacheRegionFactory
   </property>

and add dependancy to maven

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

and then you use Product product = (Product) session.get(Product.class, id); this will be second level cache(if session is close), not query.

Upvotes: 6

Related Questions