Persistences Caching - JPA


The basics

If you want to store your value
Value
in a
Database
, it is really simple.

The only thing you need is a implementation of an entity class which implements CachedJPAEntity<K,V> and getting an instance of "EntityManagerFactory".
The rest is provided by the default implementations
DefaultLRUCachingMap
,
DefaultJPAEntityValueManager
and
DefaultCachedJPAEntityRepository
.

An example using the
MyCachedJPAEntity
(see below) where both key and value is String.
LRUCachingMap<String, String> map = 
	new DefaultLRUCachingMap<String, String>(
		new DefaultJPAEntityValueManager<String,String>(
			new DefaultCachedJPAEntityRepository<String,String>(
				MyCachedJPAEntity.class,entityManagerFactory
			),PersistencesRestoreMethod.DELETE_ALL
		)
	);

Object persistence

If you want to persist an Class instance like a "Book" or "Movie" instead of "String", this is also quiet simple, but there is some few basic concepts to follow.
the class must implement "Serializable", and the value column must be declared as:

@Lob 	
@Column(name="bookvalue",nullable=false,updatable=true,length=10000)
private Book value;

LRUCachingMapFactory

There is also a factory class to all this -
LRUCachingMapFactory
.

So the code above can in reality be done like.
DefaultCachedJPALRUCachingMap<String,String> cache = LRUCachingMapFactory.createJPACache(DefaultLRUCachingMapConfiguration.ONE_DAY(),MyCachedJPAEntity.class,entityManagerFactory,PersistencesRestoreMethod.DELETE_ALL);

SQL

It will store this in a table, columns names defined in MyCachedJPAEntity (Remember to think about length):
    //(HSQLDB sql)
    create table MyCacheTable (
        mykey varchar(1000) not null,     //Primary key
        myexpiretime timestamp not null,
        mystoretime timestamp not null,
        myvalue varchar(4000) not null,
        primary key (mykey)
    )

Example - MyCachedJPAEntity

import java.util.Date;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;

@Entity(name="MyCacheTable")
public class MyCachedJPAEntity implements CachedJPAEntity<String,String> {

	private static final long serialVersionUID = -5695149079796743961L;

	@Id	
	@Column(name="mykey",length=1000,nullable=false)
	private String key;
	
	@Column(name="myvalue",length=4000,nullable=false)
	private String value;
	
	@Column(name="mystoretime",nullable=false)
	private Date storeDateTime;
	
	@Column(name="myexpiretime",nullable=false)
	private Date expireDateTime;
	
	public MyCachedJPAEntity() {
		super();
	}
	
	@Override
	public String getKey() {
		return key;
	}

	@Override
	public String getValue() {
		return value;
	}

	@Override
	public Date getStoredDateTime() {
		return storeDateTime;
	}

	@Override
	public Date getExpireDateTime() {	
		return expireDateTime;
	}
	@Override
	public void setExpireDateTime(Date expireDateTime) {
		this.expireDateTime=expireDateTime;		
	}
	@Override
	public void setKey(String key) {
		this.key = key;
	}
	@Override
	public void setStoredDateTime(Date storeDateTime) {
		this.storeDateTime = storeDateTime;
	}
	@Override
	public void setValue(String value) {
		this.value = value;
	}

}

Example - persistences.xml (src/test/resources/META-INF/persistence.xml)

<?xml version="1.0" encoding="UTF-8"?>
<persistence
    xmlns="http://java.sun.com/xml/ns/persistence"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd" version="2.0">
    <persistence-unit name="testPU" transaction-type="RESOURCE_LOCAL">
        <provider>org.hibernate.ejb.HibernatePersistence</provider>
        <class>dk.heick.caching.persistences.jpa.MyCachedJPAEntity</class>
        <class>dk.heick.caching.persistences.jpa.group.MyCachedGroupJPAID</class>
        <class>dk.heick.caching.persistences.jpa.group.MyCachedGroupJPAEntity</class>
        <exclude-unlisted-classes>true</exclude-unlisted-classes>
        <properties>
            <property name="hibernate.show_sql" value="true" />
            <property name="hibernate.format_sql" value="true" />
            <property name="hibernate.use_sql_comments" value="true" />
            <property name="hibernate.connection.url" value="jdbc:hsqldb:mem:unit-testing-jpa" />
            <property name="hibernate.connection.driver_class" value="org.hsqldb.jdbcDriver" />
            <property name="hibernate.dialect" value="org.hibernate.dialect.HSQLDialect" />
            <property name="hibernate.hbm2ddl.auto" value="create-drop" />
            <property name="hibernate.connection.username" value="sa" />
            <property name="hibernate.connection.password" value="" />
        </properties>
    </persistence-unit>
</persistence>