== JPA Cache Store
The Infinispan Community

=== Introduction
The implementation depends on JPA 2.0 specification to access entity meta model.

In normal use cases, it's recommended to leverage Infinispan for JPA second level cache and/or query cache.
However, if you'd like to use only Infinispan API and you want Infinispan to persist into a cache store using a common format (e.g., a database with well defined schema), then JPA Cache Store could be right for you.

.Things to note
* When using JPA Cache Store, the key should be the ID of the entity, while the value should be the entity object.
* Only a single `@Id` or `@EmbeddedId` annotated property is allowed.
* Auto-generated ID is not supported.
* Lastly, all entries will be stored as immortal entries.

==== Sample Usage
For example, given a persistence unit "myPersistenceUnit", and a JPA entity User:

.persistence.xml
[source,xml]
----

<persistence-unit name="myPersistenceUnit">
	...
</persistence-unit>

----

User entity class

.User.java
[source,java]
----

@Entity
public class User implements Serializable {
	@Id
	private String username;
	private String firstName;
	private String lastName;

	...
}

----

Then you can configure a cache "usersCache" to use JPA Cache Store, so that when you put data into the cache, the data would be persisted into the database based on JPA configuration.

[source,java]
----

EmbeddedCacheManager cacheManager = ...;


Configuration cacheConfig = new ConfigurationBuilder().persistence()
            .addStore(JpaStoreConfigurationBuilder.class)
            .persistenceUnitName("org.infinispan.loaders.jpa.configurationTest")
            .entityClass(User.class)
            .build();
cacheManager.defineCache("usersCache", cacheConfig);

Cache<String, User> usersCache = cacheManager.getCache("usersCache");
usersCache.put("raytsang", new User(...));

----

Normally a single Infinispan cache can store multiple types of key/value pairs, for example:

[source,java]
----

Cache<String, User> usersCache = cacheManager.getCache("myCache");
usersCache.put("raytsang", new User());
Cache<Integer, Teacher> teachersCache = cacheManager.getCache("myCache");
teachersCache.put(1, new Teacher());

----

It's important to note that, when a cache is configured to use a JPA Cache Store, that cache would only be able to store ONE type of data.

[source,java]
----

Cache<String, User> usersCache = cacheManager.getCache("myJPACache"); // configured for User entity class
usersCache.put("raytsang", new User());
Cache<Integer, Teacher> teachersCache = cacheManager.getCache("myJPACache"); // cannot do this when this cache is configured to use a JPA cache store
teachersCache.put(1, new Teacher());

----

Use of `@EmbeddedId` is supported so that you can also use composite keys.

[source,java]
----

@Entity
public class Vehicle implements Serializable {
	@EmbeddedId
	private VehicleId id;
	private String color;	...
}

@Embeddable
public class VehicleId implements Serializable
{
	private String state;
	private String licensePlate;
	...
}

----

Lastly, auto-generated IDs ﻿(e.g., `@GeneratedValue`) is not supported.
When putting things into the cache with a JPA cache store, the key should be the ID value!

=== Configuration
==== Sample Programatic Configuration

[source,java]
----

Configuration cacheConfig = new ConfigurationBuilder().persistence()
             .addStore(JpaStoreConfigurationBuilder.class)
             .persistenceUnitName("org.infinispan.loaders.jpa.configurationTest")
             .entityClass(User.class)
             .build();

----

[options="header"]
|===============
|Parameter|Description
|persistenceUnitName| JPA persistence unit name in JPA configuration ﻿(persistence.xml) that contains the JPA entity class 
|entityClass| JPA entity class that is expected to be stored in this cache.  Only one class is allowed. 
|===============

==== Sample XML Configuration

[source,xml]
----

<local-cache name="vehicleCache">
   <persistence passivation="false">
      <jpa-store xmlns="urn:infinispan:config:store:jpa:7.0"
         persistence-unit="org.infinispan.persistence.jpa.configurationTest"
         entity-class="org.infinispan.persistence.jpa.entity.Vehicle">
		/>
   </persistence>
</local-cache>

----

[options="header"]
|===============
|Parameter|Description
|persistence-unit| JPA persistence unit name in JPA configuration ﻿(persistence.xml) that contains the JPA entity class 
|entity-class|Fully qualified JPA entity class name that is expected to be stored in this cache.  Only one class is allowed.

|===============

=== Additional References
Refer to the link:$$https://github.com/infinispan/infinispan/blob/master/persistence/jpa/src/test/java/org/infinispan/persistence/jpa/JpaConfigurationTest.java$$[test case] for code samples in action. 

Refer to link:$$https://github.com/infinispan/infinispan/blob/master/persistence/jpa/src/test/resources/config/jpa-config.xml$$[test configurations] for configuration samples. 

=== Javadoc

*TODO* 

