First and second level cache
Tell the two Hibernate caches apart and know when the shared one earns its keep.
Open this lesson in the learning hubKey points
- First level is the persistence context itself. Always on, one per EntityManager, gone at commit. Nothing to configure.
- Second level is shared across transactions by the whole app. Off by default, and it needs a provider: Ehcache, Infinispan, Hazelcast.
- Turn it on with
hibernate.cache.use_second_level_cache=true, then mark entities with@Cacheand a concurrency strategy. - Only cache data read constantly and changed rarely: countries, currencies, plan definitions. Never a busy transactional table.
- It caches entities by id, not query results. The query cache is a separate switch and is easy to get wrong - measure before enabling it.
- Another application writing to the same database will not invalidate your cache. Clustered setups need care.
Example
import jakarta.persistence.Cacheable;
import org.hibernate.annotations.Cache;
import org.hibernate.annotations.CacheConcurrencyStrategy;
@Entity
@Cacheable // JPA: this entity may be cached
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE) // Hibernate: how to cache it
public class Country {
@Id
private String isoCode;
private String displayName;
}
// application.properties
// spring.jpa.properties.hibernate.cache.use_second_level_cache=true
// spring.jpa.properties.hibernate.cache.region.factory_class=jcache
The first level cache is free and unavoidable. The second level is a measured decision.
This is a reading copy. The full lesson — with the visual explainer, the interactive lab and a Run button for the code — lives in the Hibernate course, and every lesson in it is listed on the Hibernate contents page.