Hibernate.orgCommunity Documentation
We've now gone through all the main concepts and the configuration details; now we'll look a bit under the covers to understand a bit more about the architectural design of the Hibernate/JBoss Cache integration. Readers can skip this chapter if they aren't interested in a look under the covers.
The rest of Hibernate interacts with the Second Level Cache subsystem
via the org.hibernate.cache.RegionFactory
interface.
What implementation of the interface is used is determined by the
value of the hibernate.cache.region.factory_class
configuration property. The interface itself is straightforward:
void start(Settings settings, Properties properties) throws CacheException; void stop(); boolean isMinimalPutsEnabledByDefault(); long nextTimestamp(); EntityRegion buildEntityRegion(String regionName, Properties properties, CacheDataDescription metadata) throws CacheException; CollectionRegion buildCollectionRegion(String regionName, Properties properties, CacheDataDescription cdd) throws CacheException; QueryResultsRegion buildQueryResultsRegion(String regionName, Properties properties) throws CacheException; TimestampsRegion buildTimestampsRegion(String regionName, Properties properties) throws CacheException;
The start
method is invoked during
SessionFactory
startup and allows the region
factory implementation to access all the configuration settings
and initialize itself. The stop
method is
invoked during SessionFactory
shutdown.
The various build***Region
methods are invoked as
Hibernate detects it needs to cache different data. Hibernate can
invoke these methods multiple times, with different
regionName
values; each call results in the
establishment of a separate area in the underlying JBoss Cache
instance(s). For example, if an application includes an
entity class org.example.Order
and another entity
class org.example.LineItem
, you would see two
calls to buildEntityRegion
, one for the
Order
class and one for the
LineItem
class. (Note that it is possible, and
recommended, to configure one or more shared regions for entities,
collections and queries. See Section 4.2, “Organization of Data in the Cache”
for some examples.)
For each call to a build***Region
method, the
region factory returns a region object implementing the
EntityRegion
, CollectionRegion
,
QueryResultsRegion
or TimestampsRegion
interface. Each interface specifies the needed semantics for
caching the relevant type of data. Thereafter, the Hibernate core
invokes on that region object to manage reading and writing data
in the cache.
Next, we'll look at the architecture of how the JBoss Cache integration implements these interfaces, first in the case where a single JBoss Cache instance is used, next in the case where multiple instances are desired.
The following diagram illustrates the key elements involved when a single JBoss Cache instance is used:
For the single cache case, the user should specify
SharedJBossCacheRegionFactory
as their
hibernate.cache.region.factory_class
.
As part of its startup process, the region factory delegates
responsibility for providing JBoss Cache instances to an
implementation of the
org.hibernate.cache.jbc.CacheInstanceManager
interface. The region factory separately requests a JBoss Cache
instance for entities, one for collections, one for queries and one
for timestamps. Whether the CacheInstanceManager
provides the same underlying JBoss Cache instance for each
request or provides multiple caches is an implementation detail
of the CacheInstanceManager
.
SharedJBossCacheRegionFactory
creates an
instance of SharedCacheInstanceManager
as
its CacheInstanceManager
.
SharedCacheInstanceManager
uses the JBoss Cache
configuration file specified by the user to create a single
org.jboss.cache.Cache
instance, and provides
that same instance to the region factory when it requests the
cache for entities, collections, queries and timestamps.
SharedCacheInstanceManager
also creates an
org.jgroups.ChannelFactory
and passes it to
the Cache
. The ChannelFactory
provides the cache with the org.jgroups.Channel
it uses for intra-cluster communication.
At this point, the region factory has a reference to a cache
for entities, a reference to a cache for collections, one for
queries and one for timestamps. In this particular case, each
reference points to the same underlying Cache
instance. When core Hibernate invokes the
buildEntityRegion
operation on the region
factory, it instantiates an implementation of the
EntityRegion
interface that knows how to
interface with JBoss Cache, passing it a reference to its
entity cache. Same thing happens for collections, etc.
Core Hibernate invokes on the EntityRegion
,
which in turn invokes read and write operations on the underlying
JBoss Cache. The cache uses its Channel
to
propagate changes to its peers in the cluster.
When the SessionFactory
shuts down, it
invokes stop()
on the region factory, which
in turn ensures that the JBoss Cache instance is stopped and
destroyed (which in turn closes the JGroups channel).
The situation when multiple JBoss Cache instances are used is very similar to the single cache case:
Here the user should specify
MultiplexedJBossCacheRegionFactory
as their
hibernate.cache.region.factory_class
. The
MultiplexedJBossCacheRegionFactory
shares
almost all its code with SharedJBossCacheRegionFactory
;
the main difference is it constructs a different CacheInstanceManager
implementation -- the MultiplexedCacheInstanceManager
.
MultiplexedCacheInstanceManager
differs from
SharedCacheInstanceManager
in that it does
not directly instantiate a cache. Rather, it creates an
instance of org.jboss.cache.CacheManager
,
providing it with a ChannelFactory
and the
location of the user-specified cache configuration file. The
CacheManager
parses the configuration file.
MultiplexedCacheInstanceManager
analyzes
Hibernate's configuration to determine the name of the desired
cache configuration for entities, collections, queries and
timestamps. See Section 3.1.5, “The MultiplexedJBossCacheRegionFactory” for
details. It then asks its CacheManager
to
provide each needed cache. In the diagram, two different caches are needed:
One, using the "optimistic-entity" configuration, that is used for entities, collections and queries
Another, with the "timestamps-cache" configuration, that is used for timestamps.
Both the "optimistic-entity" configuration and the "timestamps-cache"
configuration specify the use of the "udp" JGroups channel
configuration, so the CacheManager
's
ChannelFactory
will ensure that they share
the underlying JGroups resources.
The way the region factory creates regions is exactly the same as in the single JBoss Cache case; the only difference is the region factory's internal reference to its timestamps cache now points to a different cache object from the entity, collection and query cache references.
Copyright © 2009 Red Hat, Inc.