Bozho
Bozho

Reputation: 597076

Infinispan JPA 2nd level cache defaults

I'm trying to configure Infinispan as a hibernate 2nd level cache. Everything is fine, but I want to tweak the default configuration, i.e. the values that all caches shared.

Caches are automatically created for entities annotated with @Cache, and I can customize them one by one in infinispan.xml by <distributed-cache-configuratoin>. However, I'd like to have default values (e.g. eviction strategy) for all of these caches.

Another thing is, I want to mark all these generated caches as "distributed" (they are "local" by default).

Here's an exceprt from my infinispan.xml:

<cache-container default-cache="default" statistics="true">
    <transport stack="external-file" />
    <!-- Configuring specifics for the User entity. How to do it globally? -->
    <distributed-cache-configuration name="user" statistics="true" />
</cache-container>

How do I do these things?

Upvotes: 5

Views: 2586

Answers (1)

Dragan Bozanovic
Dragan Bozanovic

Reputation: 23552

The default cache configuration for entities is named entity:

Cache configuration can differ for each type of data stored in the cache. In order to override the cache configuration template, use property hibernate.cache.infinispan.data-type.cfg where data-type can be one of:

entity Entities indexed by @Id or @EmbeddedId attribute.

immutable-entity Entities tagged with @Immutable annotation or set as mutable=false in mapping file.

naturalid Entities indexed by their @NaturalId attribute.

collection All collections.

timestamps Mapping entity type → last modification timestamp. Used for query caching.

query Mapping query → query result.

pending-puts Auxiliary caches for regions using invalidation mode caches.

The default for collection, immutable-entity and naturalid is also the configuration specified for entity, so you don't have to configure them separately (if you don't want separate configurations of course), as can be seen in the documentation and the source code.

Note

In general, making a Hibernate L2 cache distributed may not be a good idea, because entity instances are stored in disassembled hydrated state in the L2 cache, meaning that only ids of the associated entities are stored together with the parent entity state.

Suppose you have the following entities (A, B, C are all cachable):

@Entity
public class A {
  @ManyToOne
  private B b;

  @OneToMany
  private Collection<C> cs;
}

Even if the cs collection were cachable also, to fully assemble an entity A instance from the cache you would have the following network round trips to the other nodes of the cluster:

  1. Fetch the entity A state.
  2. Fetch the entity B state based on id stored in the b association.
  3. Fetch the collection of cs ids.
  4. For each id in the cs collection, fetch the C entity state, one by one.

Obviously, if you are assembling of collection of A instances (from a result of a query for example), all of the above is executed for each instance of A.

This all implies that reading data from the database directly (with properly configured lazy loading, using batch size for example), could be much more efficient than all of the network round trips in a distributed cache.

Also, that's one of the reasons why the entity/collection cache should run in the invalidation cluster mode (data are cached only on the node that reads/writes it, but invalidated on other nodes when changed).

Upvotes: 7

Related Questions