[[bootstrap:region]]
= Configuring a Region

A Region is required to store and retrieve data from the cache. `org.apache.geode.cache.Region` is an interface
extending `java.util.Map` and enables basic data access using familiar key-value semantics. The `Region` interface
is wired into application classes that require it so the actual Region type is decoupled from the programming model.
Typically, each Region is associated with one domain object, similar to a table in a relational database.

{data-store-name} implements the following types of Regions:

* *REPLICATE* - Data is replicated across all cache members in the cluster that define the Region. This provides
very high read performance but writes take longer to perform the replication.
* *PARTITION* - Data is partitioned into buckets (sharded) among many cache members in the cluster that define
the Region. This provides high read and write performance and is suitable for large data sets that are too big
for a single node.
* *LOCAL* - Data only exists on the local node.
* *Client* - Technically, a client Region is a LOCAL Region that acts as a PROXY to a REPLICATE or PARTITION Region
hosted on cache servers in a cluster. It may hold data created or fetched locally. Alternately, it can be empty.
Local updates are synchronized to the cache server. Also, a client Region may subscribe to events in order to
stay up-to-date (synchronized) with changes originating from remote processes that access the same server Region.

For more information about the various Region types and their capabilities as well as configuration options,
please refer to {data-store-name}'s documentation on
{x-data-store-docs}/developing/region_options/region_types.html[Region Types].

[[bootstrap:region:lookup]]
== Using an externally configured Region

To reference Regions already configured in a {data-store-name} native `cache.xml` file, use the `lookup-region` element.
Simply declare the target Region name with the `name` attribute.  For example, to declare a bean definition identified
as `ordersRegion` for an existing Region named `Orders`, you can use the following bean definition:

[source,xml]
----
<gfe:lookup-region id="ordersRegion" name="Orders"/>
----

If `name` is not specified, the bean's `id` will be used as the name of the Region. The example above becomes:

[source,xml]
----
<!-- lookup for a Region called 'Orders' -->
<gfe:lookup-region id="Orders"/>
----

CAUTION: If the Region does not exist, an initialization exception will be thrown. To configure new Regions,
proceed to the appropriate sections below.

In the previous examples, since no cache name was explicitly defined, the default naming convention (`gemfireCache`)
was used. Alternately, one can reference the cache bean with the `cache-ref` attribute:

[source,xml]
----
<gfe:cache id="myCache"/>
<gfe:lookup-region id="ordersRegion" name="Orders" cache-ref="myCache"/>
----

`lookup-region` lets you retrieve existing, pre-configured Regions without exposing the Region semantics
or setup infrastructure.

[[bootstrap:region:lookup:auto]]
== Auto Region Lookup

`auto-region-lookup` lets you import all Regions defined in a {data-store-name} native `cache.xml` file into
a Spring `ApplicationContext` when you use the `cache-xml-location` attribute on the `<gfe:cache>` element.

For instance, consider the following `cache.xml` file:

[source,xml]
----
<?xml version="1.0" encoding="UTF-8"?>
<cache xmlns="https://geode.apache.org/schema/cache"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://geode.apache.org/schema/cache https://geode.apache.org/schema/cache/cache-1.0.xsd"
       version="1.0">

  <region name="Parent" refid="REPLICATE">
    <region name="Child" refid="REPLICATE"/>
  </region>

</cache>
----

You can import the preceding `cache.xml` file as follows:

[source,xml]
----
<gfe:cache cache-xml-location="cache.xml"/>
----

You can then use the `<gfe:lookup-region>` element (for example, `<gfe:lookup-region id="Parent"/>`) to reference
specific Regions as beans in the Spring container, or you can choose to import all Regions defined in `cache.xml`
by using the following:

[source,xml]
----
<gfe:auto-region-lookup/>
----

{sdg-name} automatically creates beans for all {data-store-name} Regions defined in `cache.xml` that have not been
explicitly added to the Spring container with explicit `<gfe:lookup-region>` bean declarations.

It is important to realize that {sdg-name} uses a Spring
{spring-framework-javadoc}/org/springframework/beans/factory/config/BeanPostProcessor.html[BeanPostProcessor]
to post-process the cache after it is both created and initialized to determine the Regions defined in {data-store-name}
to add as beans in the Spring `ApplicationContext`.

You may inject these "auto-looked-up" Regions as you would any other bean defined in the Spring `ApplicationContext`,
with one exception: You may need to define a `depends-on` association with the '`gemfireCache`' bean, as follows:

[source,java]
----
package example;

import ...

@Repository("appDao")
@DependsOn("gemfireCache")
public class ApplicationDao extends DaoSupport {

    @Resource(name = "Parent")
    private Region<?, ?> parent;

    @Resource(name = "/Parent/Child")
    private Region<?, ?> child;

    ...
}
----

The preceding example only applies when you use Spring's `component-scan` functionality.

If you declare your components by using Spring XML config, then you would do the following:

[source,xml]
----
<bean class="example.ApplicationDao" depends-on="gemfireCache"/>
----

Doing so ensures that the {data-store-name} cache and all the Regions defined in `cache.xml` get created before
any components with auto-wire references when using the `<gfe:auto-region-lookup>` element.

[[bootstrap:region:overview]]
== Configuring Regions

{sdg-name} provides comprehensive support for configuring any type of Region through the following elements:

* LOCAL Region: `<local-region>`
* PARTITION Region: `<partitioned-region>`
* REPLICATE Region: `<replicated-region>`
* Client Region: `<client-region>`

See the {data-store-name} documentation for a comprehensive description of
{x-data-store-docs}/developing/region_options/region_types.html[Region Types].

[[bootstrap:region:attributes]]
=== Common Region Attributes

The following table lists the attributes available for all Region types:

[cols="1,2,2", options="header"]
.Common Region Attributes
|===
| Name
| Values
| Description

| cache-ref
| {data-store-name} Cache bean reference
| The name of the bean defining the {data-store-name} Cache (by default, 'gemfireCache').

| cloning-enabled
| boolean (default: `false`)
| When `true`, the updates are applied to a clone of the value and then the clone is saved to the cache. When `false`, the value is modified in place in the cache.

| close
| boolean (default: `false`)
| Determines whether the region should be closed at shutdown.

| concurrency-checks-enabled
| boolean (default: `true`)
| Determines whether members perform checks to provide consistent handling for concurrent or out-of-order updates to distributed regions.

| data-policy
| See {data-store-name}'s {x-data-store-javadoc}/org/apache/geode/cache/DataPolicy.html[data policy].
| The region's data policy. Note that not all data policies are supported for every Region type.

| destroy
| boolean (default: `false`)
| Determines whether the region should be destroyed at shutdown.

| disk-store-ref
| The name of a configured disk store.
| A reference to a bean created through the `disk-store` element.

| disk-synchronous
| boolean (default: `true`)
| Determines whether disk store writes are synchronous.

| id
| Any valid bean name.
| The default region name if no `name` attribute is specified.

| ignore-if-exists
| boolean (default: `false`)
| Ignores this bean definition if the region already exists in the cache, resulting in a lookup instead.

| ignore-jta
| boolean (default: `false`)
| Determines whether this Region participates in JTA (Java Transaction API) transactions.

| index-update-type
| `synchronous` or `asynchronous` (default: `synchronous`)
| Determines whether Indices are updated synchronously or asynchronously on entry creation.

| initial-capacity
| integer (default: 16)
| The initial memory allocation for the number of Region entries.

| key-constraint
| Any valid, fully-qualified Java class name.
| Expected key type.

| load-factor
| float (default: .75)
| Sets the initial parameters on the underlying `java.util.ConcurrentHashMap` used for storing region entries.

| name
| Any valid region name.
| The name of the region. If not specified, it assumes the value of the `id` attribute (that is, the bean name).

| persistent
| *boolean (default: `false`)
| Determines whether the region persists entries to local disk (disk store).

| shortcut
| See {x-data-store-javadoc}/org/apache/geode/cache/RegionShortcut.html
| The `RegionShortcut` for this region. Allows easy initialization of the region based on pre-defined defaults.

| statistics
| boolean (default: `false`)
| Determines whether the region reports statistics.

| template
| The name of a region template.
| A reference to a bean created through one of the `*region-template` elements.

| value-constraint
| Any valid, fully-qualified Java class name.
| Expected value type.
|===

[[bootstrap:region:cache-listener]]
=== `CacheListener` instances

`CacheListener` instances are registered with a Region to handle Region events, such as when entries are created,
updated, destroyed, and so on. A `CacheListener` can be any bean that implements the
{x-data-store-javadoc}/org/apache/geode/cache/CacheListener.html[`CacheListener`] interface.
A Region may have multiple listeners, declared with the `cache-listener` element nested in the containing
`*-region` element.

The following example has two declared `CacheListener's`. The first references a named, top-level Spring bean.
The second is an anonymous inner bean definition.

[source,xml]
----
<bean id="myListener" class="org.example.app.geode.cache.SimpleCacheListener"/>

<gfe:replicated-region id="regionWithListeners">
  <gfe:cache-listener>
    <!-- nested CacheListener bean reference -->
    <ref bean="myListener"/>
    <!-- nested CacheListener bean definition -->
    <bean class="org.example.app.geode.cache.AnotherSimpleCacheListener"/>
  </gfe:cache-listener>
</gfe:replicated-region>
----

The following example uses an alternate form of the `cache-listener` element with the `ref` attribute.
Doing so allows for more concise configuration when defining a single `CacheListener`.

Note: The XML namespace allows only a single `cache-listener` element, so either the style shown in
the preceding example or the style in the following example must be used.

[source,xml]
----
<beans>
  <gfe:replicated-region id="exampleReplicateRegionWithCacheListener">
    <gfe:cache-listener ref="myListener"/>
  </gfe:replicated-region>

  <bean id="myListener" class="example.CacheListener"/>
</beans>
----

WARNING: Using `ref` and a nested declaration in the `cache-listener` element is illegal.
The two options are mutually exclusive and using both in the same element results in an exception.


.Bean Reference Conventions
[NOTE]
====
The `cache-listener` element is an example of a common pattern used in the XML namespace anywhere {data-store-name}
provides a callback interface to be implemented in order to invoke custom code in response to cache or Region events.
When you use Spring's IoC container, the implementation is a standard Spring bean. In order to simplify the configuration,
the schema allows a single occurrence of the `cache-listener` element, but, if multiple instances are permitted,
it may contain nested bean references and inner bean definitions in any combination. The convention is to use
the singular form (that is, `cache-listener` vs `cache-listeners`), reflecting that the most common scenario is,
in fact, a single instance. We have already seen examples of this pattern in the <<bootstrap:cache:advanced,advanced cache>>
configuration example.
====

[[bootstrap:region:cache-loaders-writers]]
=== CacheLoaders and CacheWriters

Similar to `cache-listener`, the XML namespace provides `cache-loader` and `cache-writer` elements to register
these {data-store-name} components for a Region.

A `CacheLoader` is invoked on a cache miss to let an entry be loaded from an external data source, such as a database.
A `CacheWriter` is invoked before an entry is created or updated, to allow the entry to be synchronized to an external
data source. The main difference is that {data-store-name} supports, at most, a single instance of `CacheLoader`
and `CacheWriter` per Region. However, either declaration style may be used.

The following example declares a Region with both a `CacheLoader` and a `CacheWriter`:

[source,xml]
----
<beans>
  <gfe:replicated-region id="exampleReplicateRegionWithCacheLoaderAndCacheWriter">
    <gfe:cache-loader ref="myLoader"/>
    <gfe:cache-writer>
      <bean class="example.CacheWriter"/>
    </gfe:cache-writer>
  </gfe:replicated-region>

  <bean id="myLoader" class="example.CacheLoader">
    <property name="dataSource" ref="mySqlDataSource"/>
  </bean>

  <!-- DataSource bean definition -->
</beans>
----

See {x-data-store-javadoc}/org/apache/geode/cache/CacheLoader.html[`CacheLoader`]
and {x-data-store-javadoc}/org/apache/geode/cache/CacheWriter.html[`CacheWriter`]
in the {data-store-name} documentation for more details.

[[bootstrap:region:compression]]
== Compression

{data-store-name} Regions may also be compressed in order to reduce JVM memory consumption and pressure to possibly
avoid global GCs. When you enable compression for a Region, all values stored in memory for the Region are compressed,
while keys and indexes remain uncompressed. New values are compressed when put into the Region and all values
are decompressed automatically when read back from the Region. Values are not compressed when persisted to disk
or when sent over the wire to other peer members or clients.

The following example shows a Region with compression enabled:

[source,xml]
----
<beans>
  <gfe:replicated-region id="exampleReplicateRegionWithCompression">
    <gfe:compressor>
      <bean class="org.apache.geode.compression.SnappyCompressor"/>
    </gfe:compressor>
  </gfe:replicated-region>
</beans>
----

See {data-store-name}'s documentation for more information on
{x-data-store-docs}/managing/region_compression/region_compression.html[Region Compression].

[[bootstrap:region:off-heap]]
== Off-Heap

{data-store-name} Regions may also be configured to store Region values in off-heap memory, which is a portion of
JVM memory that is not subject to Garbage Collection (GC).  By avoid expensive GC cycles, your application
can spend more of its time on things that matter, like processing requests.

Using off-heap memory is as simple as declaring the amount of memory to use and then enabling your Regions
to use off-heap memory, as shown in the following configuration:

[source,xml]
----
<util:properties id="gemfireProperties">
    <prop key="off-heap-memory-size">200G</prop>
</util:properties>

<gfe:cache properties-ref="gemfireProperties"/>

<gfe:partitioned-region id="ExampleOffHeapRegion" off-heap="true"/>
----

You can control other aspects of off-heap memory management by setting the following {data-store-name} configuration
properties using the `&lt;gfe:cache&gt;` element:s

[source,xml]
----
<gfe:cache critical-off-heap-percentage="90" eviction-off-heap-percentage"80"/>
----

{data-store-name}'s `ResourceManager` will use these two threshold values (`critical-off-heap-percentage`
& `eviction-off-heap-percentage`) to more effectively manage the off-heap memory in much the same way
as the JVM does when managing heap memory.  {data-store-name} `ResourceManager` will prevent the cache
from consuming too much off-heap memory by evicting old data.  If the off-heap manager is unable to keep up,
then the `ResourceManager` refuses additions to the cache until the off-heap memory manager has freed up
an adequate amount of memory.

See {data-store-name}'s documentation for more information on
{x-data-store-docs}/managing/heap_use/heap_management.html[Managing Heap and Off-Heap Memory].

Specifically, read the section,
{x-data-store-docs}/managing/heap_use/off_heap_management.html[Managing Off-Heap Memory].

[[bootstrap:region:subregions]]
== Subregions

{sdg-name} also supports Sub-Regions, allowing Regions to be arranged in a hierarchical relationship.

For example, {data-store-name} allows for a `/Customer/Address` Region and a different `/Employee/Address` Region.
Additionally, a Sub-Region may have its own Sub-Regions and configuration. A Sub-Region does not inherit attributes
from its parent Region. Regions types may be mixed and matched subject to {data-store-name} constraints. A Sub-Region
is naturally declared as a child element of a Region. The Sub-Region's `name` attribute is the simple name.
The preceding example might be configured as follows:

[source,xml]
----
<beans>
  <gfe:replicated-region name="Customer">
    <gfe:replicated-region name="Address"/>
  </gfe:replicated-region>

  <gfe:replicated-region name="Employee">
    <gfe:replicated-region name="Address"/>
  </gfe:replicated-region>
</beans>
----

Note that the `Monospaced ([id])` attribute is not permitted for a Sub-Region. Sub-Regions are created with bean names
(/Customer/Address and /Employee/Address, respectively, in this case). So they may be injected into other application
beans, such as a `GemfireTemplate`, that need them by using the full path name of the Region. The full pathname
of the Region should also be used in OQL query strings.

[[bootstrap:region:templates]]
== Region Templates

{sdg-name} also supports Region templates.

This feature allows developers to define common Region configuration and attributes once and reuse the configuration
among many Region bean definitions declared in the Spring `ApplicationContext`.

{sdg-name} includes five Region template tags in its namespace:

[cols="1,2", options="header"]
.Region Template Tags
|===
| Tag Name
| Description

| `<gfe:region-template>`
| Defines common generic Region attributes. Extends `regionType` in the XML namespace.

| `<gfe:local-region-template>`
| Defines common 'Local' Region attributes. Extends `localRegionType` in the XML namespace.

| `<gfe:partitioned-region-template>`
| Defines common 'PARTITION' Region attributes. Extends `partitionedRegionType` in the XML namespace.

| `<gfe:replicated-region-template>`
| Defines common 'REPLICATE' Region attributes. Extends `replicatedRegionType` in the XML namespace.

| `<gfe:client-region-template>`
| Defines common 'Client' Region attributes. Extends `clientRegionType` in the XML namespace.
|===

In addition to the tags, concrete `<gfe:*-region>` elements (along with the abstract `<gfe:*-region-template>` elements)
have a `template` attribute used to define the Region template from which the Region inherits its configuration.
Region templates may even inherit from other Region templates.

The following example shows one possible configuration:

[source,xml]
----
<beans>
  <gfe:async-event-queue id="AEQ" persistent="false" parallel="false" dispatcher-threads="4">
    <gfe:async-event-listener>
      <bean class="example.AeqListener"/>
    </gfe:async-event-listener>
  </gfe:async-event-queue>

  <gfe:region-template id="BaseRegionTemplate" initial-capacity="51" load-factor="0.85" persistent="false" statistics="true"
      key-constraint="java.lang.Long" value-constraint="java.lang.String">
    <gfe:cache-listener>
      <bean class="example.CacheListenerOne"/>
      <bean class="example.CacheListenerTwo"/>
    </gfe:cache-listener>
    <gfe:entry-ttl timeout="600" action="DESTROY"/>
    <gfe:entry-tti timeout="300 action="INVLIDATE"/>
  </gfe:region-template>

  <gfe:region-template id="ExtendedRegionTemplate" template="BaseRegionTemplate" load-factor="0.55">
    <gfe:cache-loader>
      <bean class="example.CacheLoader"/>
    </gfe:cache-loader>
    <gfe:cache-writer>
      <bean class="example.CacheWriter"/>
    </gfe:cache-writer>
    <gfe:async-event-queue-ref bean="AEQ"/>
  </gfe:region-template>

  <gfe:partitioned-region-template id="PartitionRegionTemplate" template="ExtendedRegionTemplate"
      copies="1" load-factor="0.70" local-max-memory="1024" total-max-memory="16384" value-constraint="java.lang.Object">
    <gfe:partition-resolver>
      <bean class="example.PartitionResolver"/>
    </gfe:partition-resolver>
    <gfe:eviction type="ENTRY_COUNT" threshold="8192000" action="OVERFLOW_TO_DISK"/>
  </gfe:partitioned-region-template>

  <gfe:partitioned-region id="TemplateBasedPartitionRegion" template="PartitionRegionTemplate"
      copies="2" local-max-memory="8192" persistent="true" total-buckets="91"/>
</beans>
----

Region templates work for Sub-Regions as well. Notice that 'TemplateBasedPartitionRegion' extends 'PartitionRegionTemplate',
which extends 'ExtendedRegionTemplate', which extends 'BaseRegionTemplate'. Attributes and sub-elements defined in
subsequent, inherited Region bean definitions override what is in the parent.

=== How Templating Works

{sdg-name} applies Region templates when the Spring `ApplicationContext` configuration metadata is parsed, and therefore,
Region templates must be declared in the order of inheritance. In other words, parent templates must be defined before
child templates. Doing so ensures that the proper configuration is applied, especially when element attributes
or sub-elements are overridden.

IMPORTANT: It is equally important to remember that the Region types must only inherit from other similarly typed Regions.
For instance, it is not possible for a `<gfe:replicated-region>` to inherit from a `<gfe:partitioned-region-template>`.

NOTE: Region templates are single-inheritance.

[[bootstrap:region:regions-subregions-lookups-caution]]
=== Caution concerning Regions, Sub-Regions and Lookups

Previously, one of the underlying properties of the `replicated-region`, `partitioned-region`, `local-region`,
and `client-region` elements in the {sdg-name} XML namespace was to perform a lookup first before attempting to
create a Region. This was done in case the Region already existed, which would be the case if the Region was defined
in an imported {data-store-name} native `cache.xml` configuration file. Therefore, the lookup was performed first
to avoid any errors. This was by design and subject to change.

This behavior has been altered and the default behavior is now to create the Region first. If the Region
already exists, then the creation logic fails-fast and an appropriate exception is thrown. However, much like the
`CREATE TABLE IF NOT EXISTS ...` DDL syntax, the {sdg-name} `<gfe:*-region>` XML namespace elements now include
a `ignore-if-exists` attribute, which reinstates the old behavior by first performing a lookup of an existing Region
identified by name before attempting to create the Region. If an existing Region is found by name and `ignore-if-exists`
is set to `true`, then the Region bean definition defined in Spring configuration is ignored.

WARNING: The Spring team highly recommends that the `replicated-region`, `partitioned-region`, `local-region`,
and `client-region` XML namespace elements be strictly used for defining new Regions only. One problem that could arise
when the Regions defined by these elements already exist and the Region elements perform a lookup first is, if
you defined different Region semantics and behaviors for eviction, expiration, subscription, and so on in your
application config, then the Region definition might not match and could exhibit contrary behaviors to those required
by the application. Even worse, you might want to define the Region as a distributed Region (for example, `PARTITION`)
when, in fact, the existing Region definition is local only.

IMPORTANT: Recommended Practice - Use only `replicated-region`, `partitioned-region`, `local-region`, and `client-region`
XML namespace elements to define new Regions.

Consider the following native {data-store-name} `cache.xml` configuration file:

[source,xml]
----
<?xml version="1.0" encoding="UTF-8"?>
<cache xmlns="https://geode.apache.org/schema/cache"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://geode.apache.org/schema/cache https://geode.apache.org/schema/cache/cache-1.0.xsd"
       version="1.0">

  <region name="Customers" refid="REPLICATE">
    <region name="Accounts" refid="REPLICATE">
      <region name="Orders" refid="REPLICATE">
        <region name="Items" refid="REPLICATE"/>
      </region>
    </region>
  </region>

</cache>
----

Further, consider that you may have defined an application DAO as follows:

[source,java]
----
public class CustomerAccountDao extends GemDaoSupport {

    @Resource(name = "Customers/Accounts")
    private Region customersAccounts;

    ...
}
----

Here, we inject a reference to the `Customers/Accounts` Region in our application DAO. Consequently, it is
not uncommon for a developer to define beans for some or all of these Regions in Spring XML configuration
metadata as follows:

[source,xml]
[subs="verbatim,attributes"]
----
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:gfe="{spring-data-schema-namespace}"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="
    http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd
    {spring-data-schema-namespace} {spring-data-schema-location}
">

  <gfe:cache cache-xml-location="classpath:cache.xml"/>

  <gfe:lookup-region name="Customers/Accounts"/>
  <gfe:lookup-region name="Customers/Accounts/Orders"/>

</beans>
----

The `Customers/Accounts` and `Customers/Accounts/Orders` Regions are referenced as beans in the Spring container
as `Customers/Accounts` and `Customers/Accounts/Orders`, respectively.  The nice thing about using the `lookup-region`
element and the corresponding syntax (described earlier) is that it lets you reference a Sub-Region directly without
unnecessarily defining a bean for the parent Region (`Customers`, in this case).

Consider the following bad example, which changes the configuration metadata syntax to use the nested format:

[source,xml]
----
<gfe:lookup-region name="Customers">
  <gfe:lookup-region name="Accounts">
    <gfe:lookup-region name="Orders"/>
  </gfe:lookup-region>
</gfe:lookup-region>
----

Now consider another bad example which uses the top-level `replicated-region` element along with
the `ignore-if-exists` attribute set to perform a lookup first:

[source,xml]
----
<gfe:replicated-region name="Customers" persistent="true" ignore-if-exists="true">
  <gfe:replicated-region name="Accounts" persistent="true" ignore-if-exists="true">
    <gfe:replicated-region name="Orders" persistent="true" ignore-if-exists="true"/>
  </gfe:replicated-region>
</gfe:replicated-region>
----

The Region beans defined in the Spring `ApplicationContext` consist of the following:
`{ "Customers", "/Customers/Accounts", "/Customers/Accounts/Orders" }.` This means the dependency injected reference
shown in the earlier example (that is, `@Resource(name = "Customers/Accounts")`) is now broken, since no bean with name
`Customers/Accounts` is actually defined. For this reason, you should not configure Regions as shown in
the two preceding examples.

{data-store-name} is flexible in referencing both parent Regions and Sub-Regions with or without the leading forward
slash. For example, the parent can be referenced as `/Customers` or `Customers` and the child as `/Customers/Accounts`
or `Customers/Accounts`. However, {sdg-name} is very specific when it comes to naming beans after Regions. It always
uses the forward slash (/) to represent Sub-Regions (for example, `/Customers/Accounts`).

Therefore, you should use the non-nested `lookup-region` syntax shown earlier or define direct references with
a leading forward slash (/), as follows:

[source,xml]
----
<gfe:lookup-region name="/Customers/Accounts"/>
<gfe:lookup-region name="/Customers/Accounts/Orders"/>
----

The earlier example, where the nested `replicated-region` elements were used to reference the Sub-Regions, shows
the problem stated earlier. Are the Customers, Accounts and Orders Regions and Sub-Regions persistent or not?
They are not persistent, because the Regions were defined in the native {data-store-name} `cache.xml` configuration file
as `REPLICATE` and exist before the cache bean is initialized (once the `<gfe:cache>` element is processed).

[[bootstrap:region:eviction]]
== Data Eviction (with Overflow)

Based on various constraints, each Region can have an eviction policy in place for evicting data from memory.
Currently, in {data-store-name}, eviction applies to the Least Recently Used entry (also known as
https://en.wikipedia.org/wiki/Cache_algorithms#Least_Recently_Used[LRU]). Evicted entries are either destroyed
or paged to disk (referred to as "`overflow to disk`").

{sdg-name} supports all eviction policies (entry count, memory, and heap usage) for PARTITION Regions, REPLICATE Regions,
and client, local Regions by using the nested `eviction` element.

For example, to configure a PARTITION Region to overflow to disk if the memory size exceeds more than 512 MB,
you can specify the following configuration:

[source,xml]
----
<gfe:partitioned-region id="examplePartitionRegionWithEviction">
  <gfe:eviction type="MEMORY_SIZE" threshold="512" action="OVERFLOW_TO_DISK"/>
</gfe:partitioned-region>
----

IMPORTANT: Replicas cannot use `local destroy` eviction since that would invalidate them.
See the {data-store-name} docs for more information.

When configuring Regions for overflow, you should configure the storage through the `disk-store` element
for maximum efficiency.

For a detailed description of eviction policies, see the {data-store-name} documentation on
{x-data-store-docs}/developing/eviction/chapter_overview.html[Eviction].

[[bootstrap:region:expiration]]
== Data Expiration

{data-store-name} lets you control how long entries exist in the cache. Expiration is driven by elapsed time,
as opposed to eviction, which is driven by the entry count or heap or memory usage. Once an entry expires,
it may no longer be accessed from the cache.

{data-store-name} supports the following expiration types:

* *Time-to-Live (TTL)*: The amount of time in seconds that an object may remain in the cache after the last creation
or update. For entries, the counter is set to zero for create and put operations. Region counters are reset when
the Region is created and when an entry has its counter reset.
* *Idle Timeout (TTI)*: The amount of time in seconds that an object may remain in the cache after the last access.
The Idle Timeout counter for an object is reset any time its TTL counter is reset. In addition, an entry’s
Idle Timeout counter is reset any time the entry is accessed through a get operation or a `netSearch`.
The Idle Timeout counter for a Region is reset whenever the Idle Timeout is reset for one of its entries.

Each of these may be applied to the Region itself or to entries in the Region. {sdg-name} provides `<region-ttl>`,
`<region-tti>`, `<entry-ttl>`, and `<entry-tti>` Region child elements to specify timeout values and expiration actions.

The following example shows a `PARTITION` Region with expiration values set:

[source,xml]
----
<gfe:partitioned-region id="examplePartitionRegionWithExpiration">
  <gfe:region-ttl timeout="30000" action="INVALIDATE"/>
  <gfe:entry-tti timeout="600" action="LOCAL_DESTROY"/>
</gfe:replicated-region>
----

For a detailed description of expiration policies, see the {data-store-name} documentation on
{x-data-store-docs}/developing/expiration/chapter_overview.html[expiration].

[[bootstrap:region:expiration:annotation]]
=== Annotation-based Data Expiration

With {sdg-name}, you can define expiration policies and settings on individual Region entry values (or, to put
it differently, directly on application domain objects). For instance, you can define expiration policies on
a Session-based application domain object as follows:

[source,java]
----
@Expiration(timeout = "1800", action = "INVALIDATE")
public class SessionBasedApplicationDomainObject {
  ...
}
----

You can also specify expiration type specific settings on Region entries by using the `@IdleTimeoutExpiration`
and `@TimeToLiveExpiration` annotations for Idle Timeout (TTI) and Time-to-Live (TTL) expiration, respectively,
as the following example shows:

[source,java]
----
@TimeToLiveExpiration(timeout = "3600", action = "LOCAL_DESTROY")
@IdleTimeoutExpiration(timeout = "1800", action = "LOCAL_INVALIDATE")
@Expiration(timeout = "1800", action = "INVALIDATE")
public class AnotherSessionBasedApplicationDomainObject {
  ...
}
----

Both `@IdleTimeoutExpiration` and `@TimeToLiveExpiration` take precedence over the generic `@Expiration` annotation
when more than one expiration annotation type is specified, as shown in the preceding example. Neither
`@IdleTimeoutExpiration` nor `@TimeToLiveExpiration` overrides the other. Rather, they compliment each other
when different Region entry expiration policies, such as TTL and TTI, are configured.

[NOTE]
====
All `@Expiration`-based annotations apply only to Region entry values. Expiration for a Region is not covered by
{sdg-name}'s expiration annotation support. However, {data-store-name} and {sdg-name} do let you set Region expiration
by using the {sdg-acronym} XML namespace, as follows:

[source,xml]
----
<gfe:*-region id="Example" persistent="false">
  <gfe:region-ttl timeout="600" action="DESTROY"/>
  <gfe:region-tti timeout="300" action="INVALIDATE"/>
</gfe:*-region>
----
====

{sdg-name}'s `@Expiration` annotation support is implemented with {data-store-name}'s
{x-data-store-javadoc}/org/apache/geode/cache/CustomExpiry.html[`CustomExpiry`] interface.
See {data-store-name}'s documentation on {x-data-store-docs}/developing/expiration/configuring_data_expiration.html[configuring data expiration]
for more details

The {sdg-name} `AnnotationBasedExpiration` class (and `CustomExpiry` implementation) is responsible for processing
the {sdg-acronym} `@Expiration` annotations and applying the expiration policy configuration appropriately for Region
entry expiration on request.

To use {sdg-name} to configure specific {data-store-name} Regions to appropriately apply the expiration policy to
your application domain objects annotated with `@Expiration`-based annotations, you must:

. Define a bean in the Spring `ApplicationContext` of type `AnnotationBasedExpiration` by using the appropriate
constructor or one of the convenient factory methods. When configuring expiration for a specific expiration type,
such as Idle Timeout (TTI) or Time-to-Live (TTL), you should use one of the factory methods in
the `AnnotationBasedExpiration` class, as follows:
+
[source,xml]
----
<bean id="ttlExpiration" class="org.springframework.data.gemfire.expiration.AnnotationBasedExpiration"
      factory-method="forTimeToLive"/>

<gfe:partitioned-region id="Example" persistent="false">
    <gfe:custom-entry-ttl ref="ttlExpiration"/>
</gfe:partitioned-region>
----
+
[NOTE]
====
To configure Idle Timeout (TTI) Expiration instead, use the `forIdleTimeout` factory method
along with the `<gfe:custom-entry-tti ref="ttiExpiration"/>` element to set TTI.
====

. (optional) Annotate your application domain objects that are stored in the Region with expiration policies
and custom settings by using one of {sdg-name}'s `@Expiration` annotations: `@Expiration`, `@IdleTimeoutExpiration`,
or `@TimeToLiveExpiration`

. (optional) In cases where particular application domain objects have not been annotated with {sdg-name}'s
`@Expiration` annotations at all, but the {data-store-name} Region is configured to use {sdg-acronym}'s custom
`AnnotationBasedExpiration` class to determine the expiration policy and settings for objects stored in the Region,
you can set "`default`" expiration attributes on the `AnnotationBasedExpiration` bean by doing the following:

[source,xml]
----
<bean id="defaultExpirationAttributes" class="org.apache.geode.cache.ExpirationAttributes">
    <constructor-arg value="600"/>
    <constructor-arg value="#{T(org.apache.geode.cache.ExpirationAction).DESTROY}"/>
</bean>

<bean id="ttiExpiration" class="org.springframework.data.gemfire.expiration.AnnotationBasedExpiration"
      factory-method="forIdleTimeout">
    <constructor-arg ref="defaultExpirationAttributes"/>
</bean>

<gfe:partitioned-region id="Example" persistent="false">
    <gfe:custom-entry-tti ref="ttiExpiration"/>
</gfe:partitioned-region>
----

You may have noticed that {sdg-name}'s `@Expiration` annotations use a `String` as the attribute type rather
than, and perhaps more appropriately, being strongly typed -- for example, `int` for 'timeout' and {sdg-acronym}'s
`ExpirationActionType` for 'action'. Why is that?

Well, enter one of {sdg-name}'s other features, leveraging Spring's core infrastructure for configuration convenience:
property placeholders and Spring Expression Language (SpEL) expressions.

For instance, a developer can specify both the expiration 'timeout' and 'action' by using property placeholders
in the `@Expiration` annotation attributes, as the following example shows:

[source,java]
----
@TimeToLiveExpiration(timeout = "${geode.region.entry.expiration.ttl.timeout}"
    action = "${geode.region.entry.expiration.ttl.action}")
public class ExampleApplicationDomainObject {
  ...
}
----

Then, in your Spring XML config or in JavaConfig, you can declare the following beans:

[source,xml]
----
<util:properties id="expirationSettings">
  <prop key="geode.region.entry.expiration.ttl.timeout">600</prop>
  <prop key="geode.region.entry.expiration.ttl.action">INVALIDATE</prop>
  ...
</util:properties>

<context:property-placeholder properties-ref="expirationProperties"/>
----

This is convenient both when multiple application domain objects might share similar expiration policies and when
you wish to externalize the configuration.

However, you may want more dynamic expiration configuration determined by the state of the running system. This is where
the power of SpEL comes into play and is the recommended approach, actually. Not only can you refer to beans
in the Spring container and access bean properties, invoke methods, and so on, but the values for expiration 'timeout'
and 'action' can be strongly typed. Consider the following example (which builds on the preceding example):

[source,xml]
----
<util:properties id="expirationSettings">
  <prop key="geode.region.entry.expiration.ttl.timeout">600</prop>
  <prop key="geode.region.entry.expiration.ttl.action">#{T(org.springframework.data.gemfire.expiration.ExpirationActionType).DESTROY}</prop>
  <prop key="geode.region.entry.expiration.tti.action">#{T(org.apache.geode.cache.ExpirationAction).INVALIDATE}</prop>
  ...
</util:properties>

<context:property-placeholder properties-ref="expirationProperties"/>
----

Then, on your application domain object, you can define a timeout and an action as follows:

[source,java]
----
@TimeToLiveExpiration(timeout = "@expirationSettings['geode.region.entry.expiration.ttl.timeout']"
    action = "@expirationSetting['geode.region.entry.expiration.ttl.action']")
public class ExampleApplicationDomainObject {
  ...
}
----

You can imagine that the 'expirationSettings' bean could be a more interesting and useful object than a simple
instance of `java.util.Properties`. In the preceding example, the `properties` element (`expirationSettings`) uses SpEL
to base the action value on the actual `ExpirationAction` enumerated type, quickly leading to identified failures
if the enumerated type ever changes.

As an example, all of this has been demonstrated and tested in the {sdg-name} test suite. See the
https://github.com/spring-projects/spring-data-geode[source] for further details.

[[bootstrap:region:persistence]]
== Data Persistence

Regions can be persistent. {data-store-name} ensures that all the data you put into a Region that is configured
for persistence is written to disk in a way that is recoverable the next time you recreate the Region. Doing so lets
data be recovered after machine or process failure or even after an orderly shutdown and subsequent restart of
the {data-store-name} data node.

To enable persistence with {sdg-name}, set the `persistent` attribute to `true` on any of the `<*-region>` elements,
as the following example shows:

[source,xml]
----
<gfe:partitioned-region id="examplePersitentPartitionRegion" persistent="true"/>
----

Persistence may also be configured by setting the `data-policy` attribute. To do so, set the attribute's value to one of
{x-data-store-javadoc}/org/apache/geode/cache/DataPolicy.html[{data-store-name}'s DataPolicy settings],
as the following example shows:

[source,xml]
----
<gfe:partitioned-region id="anotherExamplePersistentPartitionRegion" data-policy="PERSISTENT_PARTITION"/>
----

The `DataPolicy` must match the Region type and must also agree with the `persistent` attribute if it is also
explicitly set. If the `persistent` attribute is set to `false` but a persistent `DataPolicy`
was specified (such as `PERSISTENT_REPLICATE` or `PERSISTENT_PARTITION`), an initialization exception is thrown.

For maximum efficiency when persisting Regions, you should configure the storage through the `disk-store` element.
The `DiskStore` is referenced by using the `disk-store-ref` attribute. Additionally, the Region may perform disk writes
synchronously or asynchronously. The following example shows a synchronous `DiskStore`:

[source,xml]
----
<gfe:partitioned-region id="yetAnotherExamplePersistentPartitionRegion" persistent="true"
    disk-store-ref="myDiskStore" disk-synchronous="true"/>
----

This is discussed further in <<bootstrap:diskstore>>.

[[bootstrap:region:subscription]]
== Subscription Policy

{data-store-name} allows configuration of {x-data-store-docs}/developing/events/configure_p2p_event_messaging.html[peer-to-peer (P2P) event messaging]
to control the entry events that the Region receives. {sdg-name} provides the `<gfe:subscription/>` sub-element to set
the subscription policy on `REPLICATE` and `PARTITION` Regions to either `ALL` or `CACHE_CONTENT`. The following example
shows a region with its subscription policy set to `CACHE_CONTENT`:

[source,xml]
----
<gfe:partitioned-region id="examplePartitionRegionWithCustomSubscription">
  <gfe:subscription type="CACHE_CONTENT"/>
</gfe:partitioned-region>
----

[[bootstrap:region:local]]
== Local Region

{sdg-name} offers a dedicated `local-region` element for creating local Regions. Local Regions, as the name implies,
are standalone, meaning that they do not share data with any other distributed system member. Other than that, all
common Region configuration options apply.

The following example shows a minimal declaration (again, the example relies on the {sdg-name} XML namespace naming
conventions to wire the cache):

[source,xml]
----
<gfe:local-region id="exampleLocalRegion"/>
----

In the preceding example, a local Region is created (if a Region by the same name does not already exist). The name of
the Region is the same as the bean ID (`exampleLocalRegion`), and the bean assumes the existence of a {data-store-name}
cache named `gemfireCache`.

[[bootstrap:region:replicate]]
== Replicated Region

One of the common Region types is a `REPLICATE` Region or "`replica`". In short, when a Region is configured to be
a `REPLICATE`, every member that hosts the Region stores a copy of the Region's entries locally. Any update to
a `REPLICATE` Region is distributed to all copies of the Region. When a replica is created, it goes through
an initialization stage, in which it discovers other replicas and automatically copies all the entries.
While one replica is initializing, you can still continue to use the other replicas.

All common configuration options are available for REPLICATE Regions. {sdg-name} offers a `replicated-region` element.
The following example shows a minimal declaration:

[source,xml]
----
<gfe:replicated-region id="exampleReplica"/>
----

See {data-store-name}'s documentation on
{x-data-store-docs}/developing/distributed_regions/chapter_overview.html[Distributed and Replicated Regions]
for more details.

[[bootstrap:region:partition]]
== Partitioned Region

The {sdg-name} XML namespace also supports `PARTITION` Regions.

To quote the {data-store-name} docs:

"`A partitioned region is a region where data is divided between peer servers hosting the region so that each peer
stores a subset of the data. When using a partitioned region, applications are presented with a logical view
of the region that looks like a single map containing all of the data in the region. Reads or writes to this map
are transparently routed to the peer that hosts the entry that is the target of the operation. {data-store-name}
divides the domain of hashcodes into buckets. Each bucket is assigned to a specific peer, but may be relocated
at any time to another peer in order to improve the utilization of resources across the cluster.`"

A `PARTITION` Region is created by using the `partitioned-region` element. Its configuration options are similar to
that of the `replicated-region` with the addition of partition-specific features, such as the number of redundant copies,
total maximum memory, number of buckets, partition resolver, and so on.

The following example shows how to set up a `PARTITION` Region with two redundant copies:

[source,xml]
----
<gfe:partitioned-region id="examplePartitionRegion" copies="2" total-buckets="17">
  <gfe:partition-resolver>
    <bean class="example.PartitionResolver"/>
  </gfe:partition-resolver>
</gfe:partitioned-region>
----

See {data-store-name}'s documentation on
{x-data-store-docs}/developing/partitioned_regions/chapter_overview.html[Partitioned Regions]
for more details.

[[bootstrap:region:partition:attributes]]
=== Partitioned Region Attributes

The following table offers a quick overview of configuration options specific to `PARTITION` Regions.
These options are in addition to the common Region configuration options
described <<bootstrap:region:attributes, earlier>>.

[cols="1,2,2", options="header"]
.partitioned-region attributes
|===
| Name
| Values
| Description

| copies
| 0..4
| The number of copies for each partition for high-availability. By default, no copies are created,
meaning there is no redundancy. Each copy provides extra backup at the expense of extra storage.

| colocated-with
| valid region name
| The name of the `PARTITION` region with which this newly created `PARTITION` Region is collocated.

| local-max-memory
| positive integer
| The maximum amount of memory (in megabytes) used by the region in *this* process.

| total-max-memory
| any integer value
| The maximum amount of memory (in megabytes) used by the region in *all* processes.

| partition-listener
| bean name
| The name of the `PartitionListener` used by this region for handling partition events.

| partition-resolver
| bean name
| The name of the `PartitionResolver` used by this region for custom partitioning.

| recovery-delay
| any long value
| The delay in milliseconds that existing members wait before satisfying redundancy after another member crashes.
-1 (the default) indicates that redundancy is not recovered after a failure.

| startup-recovery-delay
| any long value
| The delay in milliseconds that new members wait before satisfying redundancy.
-1 indicates that adding new members does not trigger redundancy recovery. The default is to recover redundancy
immediately when a new member is added.
|===

[[bootstrap:region:client]]
== Client Region

{data-store-name} supports various deployment topologies for managing and distributing data. The topic of
{data-store-name} topologies is beyond the scope of this documentation. However, to quickly recap, {data-store-name}'s
supported topologies can be classified as: peer-to-peer (p2p), client-server, and wide area network (WAN). In the last
two configurations, it is common to declare client Regions that connect to a cache server.

{sdg-name} offers dedicated support for each configuration through its <<bootstrap:cache:client, client-cache>> elements:
`client-region` and `pool`. As the names imply, `client-region` defines a client Region, while `pool` defines
a Pool of connections used and shared by the various client Regions.

The following example shows a typical client Region configuration:

[source,xml]
----
<bean id="myListener" class="example.CacheListener"/>

<!-- client Region using the default SDG gemfirePool Pool -->
<gfe:client-region id="Example">
  <gfe:cache-listener ref="myListener"/>
</gfe:client-region>

<!-- client Region using its own dedicated Pool -->
<gfe:client-region id="AnotherExample" pool-name="myPool">
  <gfe:cache-listener ref="myListener"/>
</gfe:client-region>

<!-- Pool definition -->
<gfe:pool id="myPool" subscription-enabled="true">
  <gfe:locator host="remoteHost" port="12345"/>
</gfe:pool>
----

As with the other Region types, `client-region` supports `CacheListener` instances as well as a `CacheLoader`
and a `CacheWriter`. It also requires a connection `Pool` for connecting to a set of either Locators or servers.
Each client Region can have its own `Pool`, or they can share the same one.  If a Pool is not specified, then
the "DEFAULT" Pool will be used.

NOTE: In the preceding example, the `Pool` is configured with a Locator. A Locator is a separate process used to discover
cache servers and peer data members in the distributed system and is recommended for production systems. It is also
possible to configure the `Pool` to connect directly to one or more cache servers by using the `server` element.

For a full list of options to set on the client and especially on the `Pool`, see
the {sdg-name} schema ("`<<appendix-schema>>`") and {data-store-name}'s documentation on
{x-data-store-docs}/topologies_and_comm/cs_configuration/chapter_overview.html[Client-Server Configuration].

[[bootstrap:region:client:interests]]
=== Client Interests

To minimize network traffic, each client can separately define its own 'interests' policies, indicating to
{data-store-name} the data it actually requires. In {sdg-name}, 'interests' can be defined for each client Region
separately. Both key-based and regular expression-based interest types are supported.

The following example shows both key-based and regular expression-based `interest` types:

[source,xml]
----
<gfe:client-region id="Example" pool-name="myPool">
    <gfe:key-interest durable="true" result-policy="KEYS">
        <bean id="key" class="java.lang.String">
             <constructor-arg value="someKey"/>
        </bean>
    </gfe:key-interest>
    <gfe:regex-interest pattern=".*" receive-values="false"/>
</gfe:client-region>
----

A special key, `ALL_KEYS`, means 'interest' is registered for all keys. The same can be accomplished
by using the regular expression, `".\*"`.

The `<gfe:*-interest>` key and regular expression elements support three attributes: `durable`, `receive-values`,
and `result-policy`.

`durable` indicates whether the 'interest' policy and subscription queue created for the client when the client connects
to one or more servers in the cluster is maintained across client sessions.  If the client goes away and comes back,
a `durable` subscription queue on the servers for the client is maintained while the client is disconnected. When the
client reconnects, the client receives any events that occurred while the client was disconnected from the servers
in the cluster.

A subscription queue on the servers in the cluster is maintained for each `Pool` of connections defined in the client
where a subscription has also been "`enabled`" for that `Pool`.  The subscription queue is used to store (and possibly
conflate) events sent to the client. If the subscription queue is durable, it persists between client sessions
(that is, connections), potentially up to a specified timeout.  If the client does not return within a given time frame
the client Pool subscription queue is destroyed in order to reduce resource consumption on servers in the cluster.
If the subscription queue is not `durable`, it is destroyed immediately when the client disconnects. You need to decide
whether your client should receive events that came while it was disconnected or if it needs to receive only the latest
events after it reconnects.

The `receive-values` attribute indicates whether or not the entry values are received for create and update events.
If `true`, values are received. If `false`, only invalidation events are received.

And finally, the 'result-policy` is an enumeration of: `KEYS`, `KEYS_VALUE`, and `NONE`. The default is `KEYS_VALUES`.
The `result-policy` controls the initial dump when the client first connects to initialize the local cache,
essentially seeding the client with events for all the entries that match the interest policy.

Client-side interest registration does not do much good without enabling subscription on the `Pool`, as mentioned earlier.
In fact, it is an error to attempt interest registration without subscription enabled. The following example shows
how to do so:

[source,xml]
----
<gfe:pool ... subscription-enabled="true">
  ...
</gfe:pool>
----

In addition to `subscription-enabled`, can you also set `subscription-ack-interval`,
`subscription-message-tracking-timeout`, and `subscription-redundancy`. `subscription-redundancy` is used to control how
many copies of the subscription queue should be maintained by the servers in the cluster. If redundancy is greater than
one, and the "`primary`" subscription queue (that is, the server) goes down, then a "`secondary`" subscription queue
takes over, keeping the client from missing events in a HA scenario.

In addition to the `Pool` settings, the server-side Regions use an additional attribute, `enable-subscription-conflation`,
to control the conflation of events that are sent to the clients. This can also help further minimize network traffic
and is useful in situations where the application only cares about the latest value of an entry. However, when the
application keeps a time series of events that occurred, conflation is going to hinder that use case. The default value
is `false`. The following example shows a Region configuration on the server, for which the client contains a
corresponding client `[CACHING_]PROXY` Region with interests in keys in this server Region:

[source,xml]
----
<gfe:partitioned-region name="ServerSideRegion" enable-subscription-conflation="true">
  ...
</gfe:partitioned-region>
----

To control the amount of time (in seconds) that a "`durable`" subscription queue is maintained after a client is
disconnected from the servers in the cluster, set the `durable-client-timeout` attribute on the `<gfe:client-cache>`
element as follows:

[source,xml]
----
<gfe:client-cache durable-client-timeout="600">
  ...
</gfe:client-cache>
----

A full, in-depth discussion of how client interests work and capabilities is beyond the scope of this document.

See {data-store-name}'s documentation on
{x-data-store-docs}/developing/events/how_client_server_distribution_works.html[Client-to-Server Event Distribution]
for more details.

[[bootstrap:region:json]]
== JSON Support

{data-store-name} has support for caching JSON documents in Regions, along with the ability to query stored JSON
documents using the {data-store-name} OQL (Object Query Language). JSON documents are stored internally as
{x-data-store-javadoc}/org/apache/geode/pdx/PdxInstance.html[PdxInstance] types
by using the {x-data-store-javadoc}/org/apache/geode/pdx/JSONFormatter.html[JSONFormatter] class
to perform conversion to and from JSON documents (as a `String`).

{sdg-name} provides the `<gfe-data:json-region-autoproxy/>` element to enable an
{spring-framework-docs}/#aop-introduction[AOP] component to advise appropriate, proxied Region operations,
which effectively encapsulates the `JSONFormatter`, thereby letting your applications work directly with JSON Strings.

In addition, Java objects written to JSON configured Regions are automatically converted to JSON using Jackson's
`ObjectMapper`. When these values are read back, they are returned as a JSON String.

By default, `<gfe-data:json-region-autoproxy/>` performs the conversion for all Regions. To apply this feature
to selected Regions, provide a comma-delimited list of Region bean IDs in the `region-refs` attribute.
Other attributes include a `pretty-print` flag (defaults to `false`) and `convert-returned-collections`.

Also, by default, the results of the `getAll()` and `values()` Region operations are converted for configured Regions.
This is done by creating a parallel data structure in local memory. This can incur significant overhead for large
collections, so set the `convert-returned-collections` to `false` if you would like to disable automatic conversion
for these Region operations.

NOTE: Certain Region operations (specifically those that use {data-store-name}'s proprietary `Region.Entry`, such as:
`entries(boolean)`, `entrySet(boolean)` and `getEntry()` type) are not targeted for AOP advice. In addition,
the `entrySet()` method (which returns a `Set<java.util.Map.Entry<?, ?>>`) is also not affected.

The following example configuration shows how to set the `pretty-print` and `convert-returned-collections` attributes:

[source,xml]
----
<gfe-data:json-region-autoproxy region-refs="myJsonRegion" pretty-print="true" convert-returned-collections="false"/>
----

This feature also works seamlessly with `GemfireTemplate` operations, provided that the template is declared
as a Spring bean. Currently, the native `QueryService` operations are not supported.
