First and second level cache

Hibernate · lesson 13 of 32 · 3 min read

Tell the two Hibernate caches apart and know when the shared one earns its keep.

Open this lesson in the learning hub

Key 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 @Cache and 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.