Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Hibernate second level cache problems

I have many to one relation, let's say User has a Company. Company entity does not have any other relations.

If I enable second level cache for findAll hibernate query of Company, the second time I reload page (which means that User is loaded and then also list of all Companies is loaded) I get select for each existing company (select ... from company where id=?) in hibernate output. This happens when calling findAll for Company, it looks like this (this is generic method in class which is extended with appropriate type):

return (List<T>) getHibernateTemplate().execute(new HibernateCallback() {

            public Object doInHibernate(Session session)
                    throws HibernateException, SQLException {
                Criteria c = session.createCriteria(persistentClass);
                c.setCacheable(cacheFindAll);

                return c.list();
            }
        });

I am using Jboss TreeCacheProvider in read-only strategy. If I use setCacheable(false) there are no "unwanted" selects.

Why is this happening and how can I eliminate this behavior?

like image 645
kane77 Avatar asked Mar 24 '11 21:03

kane77


1 Answers

The call setCacheable() is for enabling the query cache, see javadoc:

Enable caching of this query result, provided query caching is enabled for the underlying session

What happens is that the ids of the companies are cached but not the objects itself. If you enable the second level cache these individual company queries will be handled by the second level cache.

In order to enable second level cache you need to set the hibernate.cache.use_second_level_cache=true in the persistence.xml. Also you need to annotate you’re relations and entities you like to cache in the second level cache.

@OneToMany
@org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.READ_ONLY)
private List<Company> companies;

And entity caching:

@Entity
@org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.READ_ONLY)
public class Company {
    ...
}

BTW the second level cache will only cache relations and entities you find on id. Queries can't be cached by the second level cache and will always go to the database (or query cache).

like image 163
Kdeveloper Avatar answered Sep 28 '22 02:09

Kdeveloper