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?
Infinispan provides two CacheManager implementations: EmbeddedCacheManager. Entry point for caches when running Infinispan inside the same Java Virtual Machine (JVM) as the client application. RemoteCacheManager.
Second level shared cache is an auxiliary technique, mainly used in JPA, to enhance performance; it is used especially during large inflow, outflow of data between the database and the application.
Hibernate second level cache uses a common cache for all the session object of a session factory. It is useful if you have multiple session objects from a session factory. SessionFactory holds the second level cache data. It is global for all the session objects and not enabled by default.
Hibernate also implements a cache for query resultsets that integrates closely with the second-level cache. This is an optional feature and requires two additional physical cache regions that hold the cached query results and the timestamps when a table was last updated.
• If running JPA/Hibernate and Infinispan standalone or within third party Application Server, select the InfinispanRegionFactory as the cache region factory: ? ? This is all the configuration you need to have JPA/Hibernate use Infinispan as cache provider with the default settings.
Using Infinispan as remote Second Level Cache? Following some of the principles set out by Brian Stansberry in Using JBoss Cache 3 as a Hibernate 3.5 Second Level Cache and taking in account improvements introduced by Infinispan, an Infinispan JPA/Hibernate second level cache provider has been developed.
In JBoss Application Server 7, Infinispan is the default second level cache provider and you can find details about its configuration the AS7 JPA reference guide. Infinispan based Hibernate 2LC was developed as part of Hibernate 3.5 release and so it currently only works within AS 6 or higher.
Configure Infinispan to use your properties file with the properties-file attribute or the PooledConnectionFactoryConfiguration.propertyFile () method. 6.10. SQL cache stores SQL cache stores let you load Infinispan caches from existing database tables. Infinispan offers two types of SQL cache store:
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
wheredata-type
can be one of:
entity
Entities indexed by@Id
or@EmbeddedId
attribute.
immutable-entity
Entities tagged with@Immutable
annotation or set asmutable=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:
A
state.B
state based on id stored in the b
association.cs
ids.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).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With