==  Persistence
Persistence allows configuring external (persistent) storage engines complementary to the default in memory storage offered by Infinispan.
An external persistent storage might be useful for several reasons:

* Increased Durability. Memory is volatile, so a cache store could increase the life-span of the information store in the cache.

* Write-through. Interpose Infinispan as a caching layer between an application and a (custom) external storage engine.

* Overflow Data. By using eviction and passivation, one can store only the "hot" data in memory and overflow the data that is less frequently used to disk.

The integration with the persistent store is done through the following SPI: CacheLoader, CacheWriter, AdvancedCacheLoader and AdvancedCacheWriter (discussed in the following sections).

This SPI was refactored in Infinispan 6. It brings the following improvements over the previous (up to 5.x) persistence integration::

* Alignment with link:http://jcp.org/en/jsr/detail?id=107[JSR-107]. The link:http://docs.jboss.org/infinispan/{infinispanversion}/apidocs/org/infinispan/persistence/spi/CacheWriter.html[CacheWriter] and link:http://docs.jboss.org/infinispan/{infinispanversion}/apidocs/org/infinispan/persistence/spi/CacheLoader.html[CacheLoader] interface are similar to the the loader and writer in JSR 107. This should considerably help writing portable stores across JCache compliant vendors.

* Simplified Transaction Integration. All necessary locking is handled by Infinispan automatically and implementations don’t have to be concerned with coordinating concurrent access to the store. Even though concurrent writes on the same key are not going to happen (depending locking mode in use), implementors should expect operations on the store to happen from multiple/different threads and code the implementation accordingly.

* Parallel Iteration. It is now possible to iterate over entries in the store with multiple threads in parallel.

* Reduced Serialization. This translates in less CPU usage. The new API exposes the stored entries in serialized format. If an entry is fetched from persistent storage for the sole purpose of being sent remotely, we no longer need to deserialize it (when reading from the store) and serialize it back (when writing to the wire). Now we can write to the wire the serialized format as read from the storage directly.

[[_Data_migration_section]]
=== Data Migration

The format in which data is persisted has changed in Infinispan 6.0, so this
means that if you stored data using Infinispan 4.x or Infinispan 5.x,
Infinispan 6.0 won't be able to read it. The best way to upgrade persisted
data from Infinispan 4.x/5.x to Infinispan 6.0 is to use the mechanisms
explained in the <<_Rolling_chapter,Rolling Upgrades section>>.
In other words, by starting a rolling upgrade, data stored in Infinispan
4.x/5.x can be migrated to a Infinispan 6.0 installation where persitence
is configured with a different location for the data. The location
configuration varies according to the specific details of each cache store.

Following sections describe the SPI and also discuss the SPI implementations that Infinispan ships out of the box.

=== API

The following class diagram presents the main SPI interfaces of the persistence API:

image::images/Figure2_1_persistence_API.png[]

Some notes about the classes:

* link:http://docs.jboss.org/infinispan/{infinispanversion}/apidocs/org/infinispan/commons/io/ByteBuffer.html[ByteBuffer] - abstracts the serialized form of an object

* link:http://docs.jboss.org/infinispan/{infinispanversion}/apidocs/org/infinispan/persistence/spi/MarshalledEntry.html[MarshalledEntry] - abstracts the information held within
  a persistent store corresponding to a key-value added to the cache. Provides method for reading this information both in serialized (link:http://docs.jboss.org/infinispan/{infinispanversion}/apidocs/org/infinispan/commons/io/ByteBuffer.html[ByteBuffer]) and deserialized (Object) format. Normally data read from the store is kept in serialized format and lazily deserialized on demand, within the
  link:http://docs.jboss.org/infinispan/{infinispanversion}/apidocs/org/infinispan/persistence/spi/MarshalledEntry.html[MarshalledEntry] implementation

* link:http://docs.jboss.org/infinispan/{infinispanversion}/apidocs/org/infinispan/persistence/spi/CacheWriter.html[CacheWriter] and link:http://docs.jboss.org/infinispan/{infinispanversion}/apidocs/org/infinispan/persistence/spi/CacheLoader.html[CacheLoader] provide basic methods for reading and writing to a store

* link:http://docs.jboss.org/infinispan/{infinispanversion}/apidocs/org/infinispan/persistence/spi/AdvancedCacheLoader.html[AdvancedCacheLoader] and link:http://docs.jboss.org/infinispan/{infinispanversion}/apidocs/org/infinispan/persistence/spi/AdvancedCacheWriter.html[AdvancedCacheWriter] provide operations to manipulate the underlaying storage in bulk: parallel iteration and purging of expired entries, clear and size.

A provider might choose to only implement a subset of these interfaces:

* Not implementing the  link:http://docs.jboss.org/infinispan/{infinispanversion}/apidocs/org/infinispan/persistence/spi/AdvancedCacheWriter.html[AdvancedCacheWriter] makes the given writer not usable for purging expired entries or clear

* If a loader does not implement the link:http://docs.jboss.org/infinispan/{infinispanversion}/apidocs/org/infinispan/persistence/spi/AdvancedCacheWriter.html[AdvancedCacheWriter]
inteface, then it will not participate in preloading nor in cache iteration
(required also for stream operations).

If you're looking at migrating your existing store to the new API or to write a new store implementation, the link:https://github.com/infinispan/infinispan/blob/master/core/src/main/java/org/infinispan/persistence/file/SingleFileStore.java[SingleFileStore] might be a good starting point/example.

=== Configuration
Stores (readers and/or writers) can be configured in a chain. Cache read operation looks at all of the specified `CacheLoader` s, in the order they are configured, until it finds a valid and non-null element of data. When performing writes all cache `CacheWriter` s are written to, except if the `ignoreModifications` element has been set to true for a specific cache writer.

.Implementing both a CacheWriter and CacheLoader
IMPORTANT: it is possible and recommended for a store provider to implement both the `CacheWriter` and the `CacheLoader` interface. The stores that do this are considered both for reading and writing(assuming `read-only=false`) data.

[source,xml]
----
This is the configuration of a custom(not shipped with infinispan) store:
   <local-cache name="myCustomStore">
      <persistence passivation="false">
         <store
            class="org.acme.CustomStore"
            fetch-state="false" preload="true" shared="false"
            purge="true" read-only="false" singleton="false">

            <write-behind modification-queue-size="123" thread-pool-size="23" />

            <property name="myProp">${system.property}</property>
         </store>
      </persistence>
   </local-cache>

----

Explanation of the configuration options:

* `passivation` (false by default) has a significant impact on how Infinispan interacts with the loaders, and is discussed in the <<cache-passivation,Cache Passivation>> section.

* `class` defines the class of the store and must implement CacheLoader, CacheWriter or both

* `fetch-state` (false by default) determines whether or not to fetch the persistent state of a cache when joining a cluster. The aim here is to take the persistent state of a cache and apply it to the local cache store of the joining node. Fetch persistent state is ignored if a cache store is configured to be shared, since they access the same data. Only one configured cache loader may set this property to true; if more than one cache loader does so, a configuration exception will be thrown when starting your cache service.

* `preload` (false by default) if true, when the cache starts, data stored in the cache loader will be pre-loaded into memory. This is particularly useful when data in the cache loader is needed immediately after startup and you want to avoid cache operations being delayed as a result of loading this data lazily. Can be used to provide a 'warm-cache' on startup, however there is a performance penalty as startup time is affected by this process. Note that preloading is done in a local fashion, so any data loaded is only stored locally in the node. No replication or distribution of the preloaded data happens. Also, Infinispan only preloads up to the maximum configured number of entries in <<eviction_anchor,eviction>>.

* `shared` (false by default) indicates that the cache loader is shared among different cache instances, for example where all instances in a cluster use the same JDBC settings to talk to the same remote, shared database. Setting this to true prevents repeated and unnecessary writes of the same data to the cache loader by different cache instances.

* `purge` (false by default) empties the specified cache loader (if `read-only` is false) when the cache loader starts up.

* `read-only` (false by default) prevents new data to be persisted to the store.

* `write-behind` (disabled by default) element has to do with a persisting data asynchronously to the actual store. It is discussed in detail <<_write_behind_asynchronous, here>>.

* `singleton` (disabled by default) attribute enables modifications to be stored by only one node in the cluster, the coordinator. Essentially, whenever any data comes in to some node it is always replicated(or distributed) so as to keep the caches in-memory states in sync; the coordinator, though, has the sole responsibility of pushing that state to disk. This functionality must be configured by setting the enabled attribute to true in all nodes. Only the coordinator of the cluster will persist data, but all nodes must have this configured to prevent others from persisting as well. You cannot configure a store as shared and singleton.

* additional attributes can be configures within the `properties` section. These attributes configure aspects specific to each cache loader, e.g. the `myProp` attribute in the previous example. Other loaders, with more complex configuration, also introduce additional sub-elements to the basic configuration. See for example the JDBC cache store configuration examples below


The configuration above is used for a generic store implementation. However the store implementation provided by default with Infinispan have a more rich configuration schema, in which the `properties` section is replaced with XML attributes:

[source,xml]
----
<persistence passivation="false">
   <!-- note that class is missing and is induced by the fileStore element name -->
   <file-store
           shared="false" preload="true"
           fetch-state="true"
           read-only="false"
           purge="false"
           path="${java.io.tmpdir}">
      <write-behind flush-lock-timeout="15000" thread-pool-size="5" />
   </file-store>
</persistence>

----

The same configuration can be achieved programmatically:

[source,java]
----
   ConfigurationBuilder builder = new ConfigurationBuilder();
   builder.persistence()
         .passivation(false)
         .addSingleFileStore()
            .preload(true)
            .shared(false)
            .fetchPersistentState(true)
            .ignoreModifications(false)
            .purgeOnStartup(false)
            .location(System.getProperty("java.io.tmpdir"))
            .async()
               .enabled(true)
               .threadPoolSize(5)
            .singleton()
               .enabled(true)
               .pushStateWhenCoordinator(true)
               .pushStateTimeout(20000);

----

[[cache-passivation]]
=== Cache Passivation
A CacheWriter can be used to enforce entry passivation and activation on eviction in a cache. Cache passivation is the process of removing an object from in-memory cache and writing it to a secondary data store (e.g., file system, database) on eviction. Cache activation is the process of restoring an object from the data store into the in-memory cache when it's needed to be used. In order to fully support passivation, a store needs to be both a CacheWriter and a CacheLoader. In both cases, the configured cache store is used to read from the loader and write to the data writer.

When an eviction policy in effect evicts an entry from the cache, if passivation is enabled, a notification that the entry is being passivated will be emitted to the cache listeners and the entry will be stored. When a user attempts to retrieve a entry that was evicted earlier, the entry is (lazily) loaded from the cache loader into memory. When the entry and its children have been loaded, they're removed from the cache loader and a notification is emitted to the cache listeners that the entry has been activated. In order to enable passivation just set passivation to true (false by default). When passivation is used, only the first cache loader configured is used and all others are ignored.

==== Cache Loader Behavior with Passivation Disabled vs Enabled
When passivation is disabled, whenever an element is modified, added or removed, then that modification is persisted in the backend store via the cache loader. There is no direct relationship between eviction and cache loading. If you don't use eviction, what's in the persistent store is basically a copy of what's in memory. If you do use eviction, what's in the persistent store is basically a superset of what's in memory (i.e. it includes entries that have been evicted from memory). When passivation is enabled, there is a direct relationship between eviction and the cache loader. Writes to the persistent store via the cache loader only occur as part of the eviction process. Data is deleted from the persistent store when the application reads it back into memory. In this case, what's in memory and what's in the persistent store are two subsets of the total information set, with no intersection between the subsets.

The following is a simple example, showing what state is in RAM and in the persistent store after each step of a 6 step process:


. Insert keyOne
. Insert keyTwo
. Eviction thread runs, evicts keyOne
. Read keyOne
. Eviction thread runs, evicts keyTwo
. Remove keyTwo

.When passivation is _disabled_
. *Memory:* keyOne *Disk:* keyOne
. *Memory:* keyOne, keyTwo *Disk:* keyOne, keyTwo
. *Memory:* keyTwo *Disk:* keyOne, keyTwo
. *Memory:* keyOne, keyTwo *Disk:* keyOne, keyTwo
. *Memory:* keyOne *Disk:* keyOne, keyTwo
. *Memory:* keyOne *Disk:* keyOne

.When passivation is _enabled_
. *Memory:* keyOne *Disk:* (none)
. *Memory:* keyOne, keyTwo *Disk:* (none)
. *Memory:* keyTwo *Disk:* keyOne
. *Memory:* keyOne, keyTwo *Disk:* (none)
. *Memory:* keyOne *Disk:* keyTwo
. *Memory:* keyOne *Disk:* (none)

=== Cache Loaders and transactional caches
When a cache is transactional and a cache loader is present, the cache loader won't be enlisted in the transaction in which the cache is part.
That means that it is possible to have inconsistencies at cache loader level: the transaction to succeed applying the in-memory state but (partially) fail applying the changes to the store.
Manual recovery would not work with caches stores.


===  Write-Through And Write-Behind Caching
Infinispan can optionally be configured with one or several cache stores allowing it to store data in a persistent location such as shared JDBC database, a local filesystem, etc. Infinispan can handle updates to the cache store in two different ways:


* Write-Through (Synchronous)
* Write-Behind (Asynchronous)

==== Write-Through (Synchronous)
In this mode, which is supported in version 4.0, when clients update a cache entry, i.e. via a Cache.put() invocation, the call will not return until Infinispan has gone to the underlying cache store and has updated it. Normally, this means that updates to the cache store are done within the boundaries of the client thread.

The main advantage of this mode is that the cache store is updated at the same time as the cache, hence the cache store is consistent with the cache contents. On the other hand, using this mode reduces performance because the latency of having to access and update the cache store directly impacts the duration of the cache operation.

Configuring a write-through or synchronous cache store does not require any particular configuration option. By default, unless marked explicitly as write-behind or asynchronous, all cache stores are write-through or synchronous. Please find below a sample configuration file of a write-through unshared local file cache store:

[source,xml]
----
<persistence passivation="false">
   <file-store fetch-state="true"
               read-only="false"
               purge="false" path="${java.io.tmpdir}"/>
         </persistence>

----

==== Write-Behind (Asynchronous)
In this mode, updates to the cache are asynchronously written to the cache store. Normally, this means that updates to the cache store are done by a separate thread to the client thread interacting with the cache.

One of the major advantages of this mode is that the performance of a cache operation does not get affected by the update of the underlying store. On the other hand, since the update happens asynchronously, there's a time window during the which the cache store can contain stale data compared to the cache. Even within write-behind, there are different strategies that can be used to store data:

===== Unscheduled Write-Behind Strategy
In this mode, which is supported in version 4.0, Infinispan tries to store changes as quickly as possible by taking the pending changes and applying them in parallel. Normally, this means that there are several threads waiting for modifications to occur and once they're available, they apply them to underlying cache store.

This strategy is suited for cache stores with low latency and cheap operation cost. One such example would a local unshared file based cache store, where the cache store is local to the cache itself. With this strategy, the window of inconsistency between the contents of the cache and the cache store are reduced to the lowest possible time. Please find below a sample configuration file of this strategy:

[source,xml]
----
<persistence passivation="false">
   <file-store fetch-state="true"
               read-only="false"
               purge="false" path="${java.io.tmpdir}">
   <!-- write behind configuration starts here -->
   <write-behind />
   <!-- write behind configuration ends here -->
   </file-store>
</persistence>
----

===== Scheduled Write-Behind Strategy
First of all, please note that this strategy is not included in version 4.0 but it will be implemented at a later stage. link:https://jira.jboss.org/jira/browse/ISPN-328[ISPN-328] has been created to track this feature request. If you want it implemented, please vote for it on that page, and watch it to be notified of any changes. The following explanation refers to how we envision it to work.

In this mode, Infinispan would periodically store changes to the underlying cache store. The periodicity could be defined in seconds, minutes, days, etc.

Since this strategy is oriented at cache stores with high latency or expensive operation cost, it makes sense to coalesce changes, so that if there are multiple operations queued on the same key, only the latest value is applied to cache store. With this strategy, the window of inconsistency between the contents of the cache and the cache store depends on the delay or periodicity configured. The higher the periodicity, the higher the chance of inconsistency.


=== Filesystem based cache stores

A filesystem-based cache store is typically used when you want to have a
cache with a cache store available locally which stores data that has
overflowed from memory, having exceeded size and/or time restrictions.

WARNING: Usage of filesystem-based cache stores on shared filesystems like NFS,
Windows shares, etc. should be avoided as these do not implement proper
file locking and can cause data corruption. File systems are inherently
not transactional, so when attempting to use your cache in a transactional
context, failures when writing to the file (which happens during the commit
phase) cannot be recovered.

==== Single File Store

Starting with Infinispan 6.0, a new file cache store has been created called
single file cache store. The old pre-6.0 file cache store has been completely
removed, and it's no longer configurable.

NOTE: Check <<_Data_migration_section,Data Migration section>> for information
on how to migrate old file based cache store data to the new single file
cache store.

The new single file cache store keeps all data in a single file. The way it
looks up data is by keeping an in-memory index of keys and the positions of
their values in this file. This results in greater performance compared to old
file cache store. There is one caveat though. Since the single file based
cache store keeps keys in memory, it can lead to increased memory consumption,
and hence it's not recommended for caches with big keys.

In certain use cases, this cache store suffers from fragmentation: if you
store larger and larger values, the space is not reused and instead the entry
is appended at the end of the file. The space (now empty) is reused only if you
write another entry that can fit there. Also, when you remove all entries from
the cache, the file won't shrink, and neither will be de-fragmented.

These are the available configuration options for the single file cache store:

* `path` where data will be stored. (e.g., `path="/tmp/myDataStore"`).
By default, the location is `Infinispan-SingleFileStore`.

* `max-entries` specifies the maximum number of entries to keep in this file
store. As mentioned before, in order to speed up lookups, the single file
cache store keeps an index of keys and their corresponding position in the
file. To avoid this index resulting in memory consumption problems, this
cache store can bounded by a maximum number of entries that it stores. If
this limit is exceeded, entries are removed permanently using the LRU
algorithm both from  the in-memory index and the underlying file based
cache store. So, setting a maximum limit only makes sense when Infinispan is
used as a cache, whose contents can be recomputed or they can be retrieved
from the authoritative data store. If this maximum limit is set when the
Infinispan is used as an authoritative data store, it could lead to data
loss, and hence it's not recommended for this use case. The default value is
`-1` which means that the file store size is unlimited.

[source,xml]
----

<persistence>
   <file-store path="/tmp/myDataStore" max-entries="5000"/>
</persistence>

----

[source,java]
----

ConfigurationBuilder b = new ConfigurationBuilder();
b.persistence()
    .addSingleFileStore()
    .location("/tmp/myDataStore")
    .maxEntries(5000);

----

=== JDBC based cache loaders
Based on the type of keys to be persisted, there are three JDBC cache loaders:

*  link:http://docs.jboss.org/infinispan/{infinispanversion}/apidocs/org/infinispan/persistence/jdbc/binary/JdbcBinaryStore.html[JdbcBinaryStore] - can store any type of keys. It stores all the keys that have the same hash value (hashCode method on key) in the same table row/blob, having as primary key the hash value. While this offers great flexibility (can store any key type), it impacts concurrency/throughput. E.g. If storing k1,k2 and k3 keys, and keys had same hash code, then they'd persisted in the same table row. Now, if 3 threads try to concurrently update k1, k2 and k3 respectively, they would need to do it sequentially since these threads would be updating the same row.

*  link:http://docs.jboss.org/infinispan/{infinispanversion}/apidocs/org/infinispan/persistence/jdbc/stringbased/JdbcStringBasedStore.html[JdbcStringBasedStore] - stores each key in its own row, increasing throughput under concurrent load. In order to store each key in its own column, it relies on a (pluggable) bijection that maps the each key to a String object. The bijection is defined by the Key2StringMapper interface. Infinispans ships a default implementation (smartly named link:http://docs.jboss.org/infinispan/{infinispanversion}/apidocs/org/infinispan/persistence/keymappers/DefaultTwoWayKey2StringMapper.html[DefaultTwoWayKey2StringMapper] ) that knows how to handle primitive types.

*  link:http://docs.jboss.org/infinispan/{infinispanversion}/apidocs/org/infinispan/persistence/jdbc/mixed/JdbcMixedStore.html[JdbcMixedStore] - it is a hybrid implementation that, based on the key type, delegates to either link:http://docs.jboss.org/infinispan/{infinispanversion}/apidocs/org/infinispan/persistence/jdbc/binary/JdbcBinaryStore.html[JdbcBinaryStore] or link:http://docs.jboss.org/infinispan/{infinispanversion}/apidocs/org/infinispan/persistence/jdbc/stringbased/JdbcStringBasedStore.html[JdbcStringBasedStore].

==== Which JDBC cache loader should I use?

It is generally preferable to use link:http://docs.jboss.org/infinispan/{infinispanversion}/apidocs/org/infinispan/persistence/jdbc/stringbased/JdbcStringBasedStore.html[JdbcStringBasedStore] when you are in control of the key types, as it offers better throughput under heavy load. One scenario in which it is not possible to use it though, is when you can't write a link:http://docs.jboss.org/infinispan/{infinispanversion}/apidocs/org/infinispan/persistence/keymappers/Key2StringMapper.html[Key2StringMapper] to map the keys to to string objects (e.g. when you don't have control over the types of the keys, for whatever reason). Then you should use either link:http://docs.jboss.org/infinispan/{infinispanversion}/apidocs/org/infinispan/persistence/jdbc/binary/JdbcBinaryStore.html[JdbcBinaryStore] or link:http://docs.jboss.org/infinispan/{infinispanversion}/apidocs/org/infinispan/persistence/jdbc/mixed/JdbcMixedStore.html[JdbcMixedStore] . The later is preferred to the former when the majority of the keys are handled by link:http://docs.jboss.org/infinispan/{infinispanversion}/apidocs/org/infinispan/persistence/jdbc/stringbased/JdbcStringBasedStore.html[JdbcStringBasedStore] , but you still have some keys you cannot convert through link:http://docs.jboss.org/infinispan/{infinispanversion}/apidocs/org/infinispan/persistence/keymappers/DefaultTwoWayKey2StringMapper.html[DefaultTwoWayKey2StringMapper].

==== Connection management (pooling)
In order to obtain a connection to the database all the JDBC cache loaders rely on a link:http://docs.jboss.org/infinispan/{infinispanversion}/apidocs/org/infinispan/persistence/jdbc/connectionfactory/ConnectionFactory.html[ConnectionFactory] implementation. The connection factory is specified programmatically using one of the connectionPool(), dataSource() or simpleConnection() methods on the JdbcBinaryCacheStoreConfigurationBuilder class or declaratively using one of the `<connectionPool />`, `<dataSource />` or `<simpleConnection />` elements. Infinispan ships with three ConnectionFactory implementations:


*  link:http://docs.jboss.org/infinispan/{infinispanversion}/apidocs/org/infinispan/persistence/jdbc/connectionfactory/PooledConnectionFactory.html[PooledConnectionFactory] is a factory based on link:http://sourceforge.net/projects/c3p0/[C3P0] . Refer to link:http://docs.jboss.org/infinispan/{infinispanversion}/apidocs/org/infinispan/persistence/jdbc/connectionfactory/PooledConnectionFactory.html[javadoc] for details on configuring it.


*  link:http://docs.jboss.org/infinispan/{infinispanversion}/apidocs/org/infinispan/persistence/jdbc/connectionfactory/ManagedConnectionFactory.html[ManagedConnectionFactory] is a connection factory that can be used within managed environments, such as application servers. It knows how to look into the JNDI tree at a certain location (configurable) and delegate connection management to the DataSource. Refer to javadoc link:http://docs.jboss.org/infinispan/{infinispanversion}/apidocs/org/infinispan/persistence/jdbc/connectionfactory/ManagedConnectionFactory.html[javadoc] for details on how this can be configured.


*  link:http://docs.jboss.org/infinispan/{infinispanversion}/apidocs/org/infinispan/persistence/jdbc/connectionfactory/SimpleConnectionFactory.html[SimpleConnectionFactory] is a factory implementation that will create database connection on a per invocation basis. Not recommended in production.

The `PooledConnectionFactory` is generally recommended for stand-alone deployments (i.e. not running within AS or servlet container). `ManagedConnectionFactory` can be used when running in a managed environment where a `DataSource` is present, so that connection pooling is performed within the `DataSource`.

==== Sample configurations
Below is a sample configuration for the link:http://docs.jboss.org/infinispan/{infinispanversion}/apidocs/org/infinispan/persistence/jdbc/binary/JdbcBinaryStore.html[JdbcBinaryStore] . For detailed description of all the parameters used refer to the link:http://docs.jboss.org/infinispan/{infinispanversion}/apidocs/org/infinispan/persistence/jdbc/binary/JdbcBinaryStore.html[JdbcBinaryStore] .  Please note the use of multiple XML schemas, since each store has its own schema.

[source,xml]
----
<persistence>
   <binary-keyed-jdbc-store fetch-state="false" read-only="false" purge="false">
      <simple-connection connection-url="jdbc:h2:mem:infinispan_binary_based;DB_CLOSE_DELAY=-1" driver="org.h2.Driver" username="sa"/>
      <binary-keyed-table prefix="ISPN_BUCKET_TABLE" drop-on-exit="true" create-on-start="true">
         <id-column name="ID_COLUMN" type="VARCHAR(255)" />
         <data-column name="DATA_COLUMN" type="BINARY" />
         <timestamp-column name="TIMESTAMP_COLUMN" type="BIGINT" />
      </binary-keyed-table>
   </binary-keyed-jdbc-store>
</persistence>

----

[source,java]
----

ConfigurationBuilder builder = new ConfigurationBuilder();
builder.persistence()
      .addStore(JdbcBinaryStoreConfigurationBuilder.class)
         .fetchPersistentState(false)
         .ignoreModifications(false)
         .purgeOnStartup(false)
         .table()
         .dropOnExit(true)
         .createOnStart(true)
         .tableNamePrefix("ISPN_BUCKET_TABLE")
         .idColumnName("ID_COLUMN").idColumnType("VARCHAR(255)")
         .dataColumnName("DATA_COLUMN").dataColumnType("BINARY")
         .timestampColumnName("TIMESTAMP_COLUMN").timestampColumnType("BIGINT")
         .connectionPool()
            .connectionUrl("jdbc:h2:mem:infinispan_binary_based;DB_CLOSE_DELAY=-1")
            .username("sa")
            .driverClass("org.h2.Driver");

----

Below is a sample configuration for the link:http://docs.jboss.org/infinispan/{infinispanversion}/apidocs/org/infinispan/persistence/jdbc/stringbased/JdbcStringBasedStore.html[JdbcStringBasedStore] . For detailed description of all the parameters used refer to the link:http://docs.jboss.org/infinispan/{infinispanversion}/apidocs/org/infinispan/persistence/jdbc/stringbased/JdbcStringBasedStore.html[JdbcStringBasedStore] .

[source,xml]
----
<persistence>
   <string-keyed-jdbc-store fetch-state="false" read-only="false" purge="false">
      <connection-pool connection-url="jdbc:h2:mem:infinispan_string_based;DB_CLOSE_DELAY=-1" username="sa" driver="org.h2.Driver"/>
      <string-keyed-table drop-on-exit="true" create-on-start="true" prefix="ISPN_STRING_TABLE">
         <id-column name="ID_COLUMN" type="VARCHAR(255)" />
         <data-column name="DATA_COLUMN" type="BINARY" />
         <timestamp-column name="TIMESTAMP_COLUMN" type="BIGINT" />
      </string-keyed-table>
   </string-keyed-jdbc-store>
</persistence>

----

[source,java]
----

ConfigurationBuilder builder = new ConfigurationBuilder();
builder.persistence().addStore(JdbcStringBasedStoreConfigurationBuilder.class)
      .fetchPersistentState(false)
      .ignoreModifications(false)
      .purgeOnStartup(false)
      .table()
         .dropOnExit(true)
         .createOnStart(true)
         .tableNamePrefix("ISPN_STRING_TABLE")
         .idColumnName("ID_COLUMN").idColumnType("VARCHAR(255)")
         .dataColumnName("DATA_COLUMN").dataColumnType("BINARY")
         .timestampColumnName("TIMESTAMP_COLUMN").timestampColumnType("BIGINT")
      .connectionPool()
         .connectionUrl("jdbc:h2:mem:infinispan_binary_based;DB_CLOSE_DELAY=-1")
         .username("sa")
         .driverClass("org.h2.Driver");

----

Below is a sample configuration for the link:http://docs.jboss.org/infinispan/{infinispanversion}/apidocs/org/infinispan/persistence/jdbc/mixed/JdbcMixedStore.html[JdbcMixedStore] . For detailed description of all the parameters used refer to the link:http://docs.jboss.org/infinispan/{infinispanversion}/apidocs/org/infinispan/persistence/jdbc/mixed/JdbcMixedStore.html[JdbcMixedStore] .

[source,xml]
----
<persistence>
   <mixed-keyed-jdbc-store fetch-state="false" read-only="false" purge="false">
      <simple-connection connection-url="jdbc:h2:mem:infinispan_binary_based;DB_CLOSE_DELAY=-1" driver="org.h2.Driver" username="sa"/>
      <string-keyed-table prefix="ISPN_MIXED_STR_TABLE" drop-on-exit="true" create-on-start="true">
         <id-column name="ID_COLUMN" type="VARCHAR(255)" />
         <data-column name="DATA_COLUMN" type="BINARY" />
         <timestamp-column name="TIMESTAMP_COLUMN" type="BIGINT" />
      </string-keyed-table>
      <binary-keyed-table prefix="ISPN_MIXED_BINARY_TABLE" drop-on-exit="true" create-on-start="true">
         <id-column name="ID_COLUMN" type="VARCHAR(255)" />
         <data-column name="DATA_COLUMN" type="BINARY" />
         <timestamp-column name="TIMESTAMP_COLUMN" type="BIGINT" />
      </binary-keyed-table>
   </mixed-keyed-jdbc-store>
</persistence>

----

[source,java]
----

ConfigurationBuilder builder = new ConfigurationBuilder();
builder.persistence().addStore(JdbcMixedStoreConfigurationBuilder.class)
      .fetchPersistentState(false).ignoreModifications(false).purgeOnStartup(false)
      .stringTable()
         .dropOnExit(true)
         .createOnStart(true)
         .tableNamePrefix("ISPN_MIXED_STR_TABLE")
         .idColumnName("ID_COLUMN").idColumnType("VARCHAR(255)")
         .dataColumnName("DATA_COLUMN").dataColumnType("BINARY")
         .timestampColumnName("TIMESTAMP_COLUMN").timestampColumnType("BIGINT")
      .binaryTable()
         .dropOnExit(true)
         .createOnStart(true)
         .tableNamePrefix("ISPN_MIXED_BINARY_TABLE")
         .idColumnName("ID_COLUMN").idColumnType("VARCHAR(255)")
         .dataColumnName("DATA_COLUMN").dataColumnType("BINARY")
         .timestampColumnName("TIMESTAMP_COLUMN").timestampColumnType("BIGINT")
      .connectionPool()
         .connectionUrl("jdbc:h2:mem:infinispan_binary_based;DB_CLOSE_DELAY=-1")
         .username("sa")
         .driverClass("org.h2.Driver");
----

Finally, below is an example of a JDBC cache store with a managed connection factory, which is chosen implicitly by specifying a datasource JNDI location:

[source,xml]
----

<string-keyed-jdbc-store xmlns="urn:infinispan:config:store:jdbc:7.0" fetch-state="false" read-only="false" purge="false">
   <data-source jndi-url="java:/StringStoreWithManagedConnectionTest/DS" />
   <string-keyed-table drop-on-exit="true" create-on-start="true" prefix="ISPN_STRING_TABLE">
      <id-column name="ID_COLUMN" type="VARCHAR(255)" />
      <data-column name="DATA_COLUMN" type="BINARY" />
      <timestamp-column name="TIMESTAMP_COLUMN" type="BIGINT" />
   </string-keyed-table>
</string-keyed-jdbc-store>

----

[source,java]
----

ConfigurationBuilder builder = new ConfigurationBuilder();
builder.persistence().addStore(JdbcStringBasedStoreConfigurationBuilder.class)
      .fetchPersistentState(false).ignoreModifications(false).purgeOnStartup(false)
      .table()
         .dropOnExit(true)
         .createOnStart(true)
         .tableNamePrefix("ISPN_STRING_TABLE")
         .idColumnName("ID_COLUMN").idColumnType("VARCHAR(255)")
         .dataColumnName("DATA_COLUMN").dataColumnType("BINARY")
         .timestampColumnName("TIMESTAMP_COLUMN").timestampColumnType("BIGINT")
      .dataSource()
         .jndiUrl("java:/StringStoreWithManagedConnectionTest/DS");

----

.Apache Derby users
NOTE: If you're connecting to an Apache Derby database, make sure you set dataColumnType to BLOB: `<data-column name="DATA_COLUMN" type="BLOB"/>`

=== Remote store
The `RemoteStore` is a cache loader and writer implementation that stores data in a remote infinispan cluster. In order to communicate with the remote cluster, the `RemoteStore` uses the HotRod client/server architecture. HotRod bering the load balancing and fault tolerance of calls and the possibility to fine-tune the connection between the RemoteCacheStore and the actual cluster. Please refer to Hot Rod for more information on the protocol, client and server configuration. For a list of RemoteStore configuration refer to the link:http://docs.jboss.org/infinispan/{infinispanversion}/apidocs/org/infinispan/persistence/remote/configuration/RemoteStoreConfigurationBuilder.html[javadoc] . Example:

[source,xml]
----
<persistence>
   <remote-store xmlns="urn:infinispan:config:remote:7.0" cache="mycache" raw-values="true">
      <remote-server host="one" port="12111" />
      <remote-server host="two" />
      <connection-pool max-active="10" exhausted-action="CREATE_NEW" />
      <write-behind />
   </remote-store>
</persistence>
----

[source,java]
----

ConfigurationBuilder b = new ConfigurationBuilder();
b.persistence().addStore(RemoteStoreConfigurationBuilder.class)
      .fetchPersistentState(false)
      .ignoreModifications(false)
      .purgeOnStartup(false)
      .remoteCacheName("mycache")
      .rawValues(true)
.addServer()
      .host("one").port(12111)
      .addServer()
      .host("two")
      .connectionPool()
      .maxActive(10)
      .exhaustedAction(ExhaustedAction.CREATE_NEW)
      .async().enable();

----

In this sample configuration, the remote cache store is configured to use the remote cache named "mycache" on servers "one" and "two". It also configures connection pooling and provides a custom transport executor. Additionally the cache store is asynchronous.

=== Cluster cache loader
The ClusterCacheLoader is a cache loader implementation that retrieves data from other cluster members.

It is a cache loader only as it doesn't persist anything (it is not a Store), therefore features like _fetchPersistentState_ (and like) are not applicable.

A cluster cache loader can be used as a non-blocking (partial) alternative to _stateTransfer_ : keys not already available in the local node are fetched on-demand from other nodes in the cluster. This is a kind of lazy-loading of the cache content.

[source,xml]
----

<persistence>
   <cluster-loader remote-timeout="500"/>
</persistence>

----

[source,java]
----

ConfigurationBuilder b = new ConfigurationBuilder();
b.persistence()
    .addClusterLoader()
    .remoteCallTimeout(500);

----

For a list of ClusterCacheLoader configuration refer to the link:http://docs.jboss.org/infinispan/{infinispanversion}/apidocs/org/infinispan/configuration/cache/ClusterLoaderConfiguration.html[javadoc] .

NOTE: The ClusterCacheLoader does not support preloading(preload=true). It also won't provide state if fetchPersistentSate=true.

=== Custom Cache Store deployment
A Custom Cache Store might be packaged into a separate JAR file and deployed in a HotRod server using the following steps:

1. Create a JAR file (or use a link:https://github.com/infinispan/infinispan-cachestore-archetype[Custom Cache Store Archetype]) and implement one of the interfaces within it:
* `org.infinispan.persistence.spi.AdvancedCacheWriter`
* `org.infinispan.persistence.spi.AdvancedCacheLoader`
* `org.infinispan.persistence.spi.CacheLoader`
* `org.infinispan.persistence.spi.CacheWriter`
* `org.infinispan.persistence.spi.ExternalStore`
* `org.infinispan.persistence.spi.AdvancedLoadWriteStore`
2. It is possible to create a Custom Cache Store configuration. This requires implementing `AbstractStoreConfiguration` and `AbstractStoreConfigurationBuilder`. Additionally, 2 annotations need to be added to the configuration - `@ConfigurationFor` and `@BuiltBy`. However this is an optional step.
3. Create a proper file in `META-INF/services/`, which reflects the implementation:
* `/META-INF/services/org.infinispan.persistence.spi.AdvancedCacheWriter`
* `/META-INF/services/org.infinispan.persistence.spi.AdvancedCacheLoader`
* `/META-INF/services/org.infinispan.persistence.spi.CacheLoader`
* `/META-INF/services/org.infinispan.persistence.spi.CacheWriter`
* `/META-INF/services/org.infinispan.persistence.spi.ExternalStore`
* `/META-INF/services/org.infinispan.persistence.spi.AdvancedLoadWriteStore`
Write the fully qualified class name of the Custom Cache Store class implementation.
4. Deploy the JAR file in the Infinispan Server.

=== Command-Line Interface cache loader
The Command-Line Interface (CLI) cache loader is a cache loader implementation
that retrieves data from another Infinispan node using the CLI. The node to
which the CLI connects to could be a standalone node, or could be a node that
it's part of a cluster. This cache loader is read-only, so it will only be
used to retrieve data, and hence, won't be used when persisting data.

The CLI cache loader is configured with a connection URL pointing to the
Infinispan node to which connect to. Here is an example:

NOTE: Details on the format of the URL and how to make sure a node can
receive invocations via the CLI can be found in the
<<_CLI_chapter,Command-Line Interface chapter>>.

[source,xml]
----

<persistence>
   <cli-loader connection="jmx://1.2.3.4:4444/MyCacheManager/myCache" />
</persistence>

----

[source,java]
----

ConfigurationBuilder b = new ConfigurationBuilder();
b.persistence()
    .addStore(CLInterfaceLoaderConfigurationBuilder.class)
    .connectionString("jmx://1.2.3.4:4444/MyCacheManager/myCache");

----


=== More implementations
Many more cache loader and cache store implementations exist.
Visit link:http://infinispan.org/cache-store-implementations[this website] for more details.


