com.google.sitebricks.persist.EntityStore Maven / Gradle / Ivy
package com.google.sitebricks.persist;
import net.sf.cglib.proxy.Enhancer;
import javax.inject.Inject;
import java.io.Serializable;
import java.util.List;
import java.util.Map;
/**
* An abstraction over a session to the persistence store. Either use this or
* the datastore's session API directly. This is analogous to Hibernate's Session,
* JPA's EntityManager, etc. It ensures that there is an active, dedicated logical
* session to the database for the current threads.
*
* Here is an example using the Redis module:
*
* public class MyPersonSaver {
* {@literal @}Inject Provider<EntityStore> store;
*
* {@literal @}Work
* public void makePerson() {
* Parameter p = new Parameter("name", "Jason");
*
* store.get().save(p);
* }
* }
*
*
* Notice the @Work
annotation, which tells Sitebricks that the method
* makePerson()
will do work with a datastore. During this method Sitebricks
* ensures that a logical session to the datastore is open and accessible via EntityStore
.
*
* If you wish to use the datastore's API directly, here is the above example showing how (in this
* case we're using Jedis
as the Redis client API):
*
* public class MyPersonSaver {
* {@literal @}Inject Provider<Jedis> jedis;
*
* {@literal @}Work
* public void makePerson() {
* jedis.get().set("name", "Jason");
* }
* }
*
*
* Note that Sitebricks ensures that the session is closed correctly after the method exits, and
* any resources held open are returned to the appropriate pools.
*
*
*
* The main advantage to using EntityStore
is that you can plug the underlying
* datastore in and out relatively easily. But it also means you have to conform to using
* EntityStore
and friends everywhere. If you don't want to you can safely use
* the API of any supported underlying datastore implementation instead.
*
* @author [email protected] (Dhanji R. Prasanna)
*/
public abstract class EntityStore {
@Inject
private EntityMetadata metadata;
/**
* Save an object to the entity store. This object must be an instance of a class
* known to Sitebricks.
*/
public abstract Serializable save(T t);
/**
* Delete a persistent object from the underlying datastore.
*/
public abstract void remove(Class type, Serializable key);
/**
* Returns an instance of the found class represented by the (primary) key provided.
* The key may be any serializable type supported by the specific entity store. If no
* such key was found, this method returns null.
*/
public abstract T find(Class type, Serializable key);
/**
* Create an entity query (a type-safe abstract object query) that can be used to
* query items stored in the underlying datastore. The returned query is not threadsafe.
*/
public abstract List all(Class type);
/**
* Create an entity query (a type-safe abstract object query) that can be used to
* query items stored in the underlying datastore. The returned query is not threadsafe.
*/
public EntityQuery from(T entityTopic) {
return new TypesafeEntityQuery(entityTopic, this);
}
/**
* Creates a topic that can be used in an EntityQuery (see {@link #from} for details.
*/
public T topic(Class entity) {
EntityMetadata.EntityDescriptor descriptor = metadata.of(entity);
@SuppressWarnings({"unchecked", "UnnecessaryLocalVariable"}) // Cast is guaranteed by enhancer.
T proxy = (T) Enhancer.create(entity, new Class[] { TopicProxy.HasCalledFields.class },
new TopicProxy(descriptor));
return proxy;
}
/**
* Datastore specific implementation of query execution.
*/
protected abstract List execute(Class type, Map> query, int offset, int limit);
/**
* Datastore specific implementation of bulk deletion query.
*/
protected abstract void executeDelete(Class type,
Map> matcherMap);
/**
* Returns the underlying implementation API (you should rarely ever need this).
*/
public abstract Object delegate();
/**
* Returns the underlying implementation API (you should rarely ever need this).
*/
public interface EntityTransaction {
void commit();
void rollback();
}
}