Object Storage
Using XOOM Symbio to store objects.
An ObjectStore provides the protocol for reactively persisting and reconstituting objects. Storing objects has the advantage of searching for given instances by any number of their attributes/properties, effectively as if the objects are living in memory with only the need to ask for them by means of partial state characteristics. The objects stored are typically state types of Entity/Aggregate instances, which have unique identities. These state types are extenders of the StateObject abstract base class.
import io.vlingo.xoom.symbio.store.object.StateObject;
public final class ProductState extends StateObject {
private String name;
private SKU sku;
private RFID rfid;
private Money price;
...
public ProductState(long id, String name, SKU sku, RFID rfid, Money price) {
super(id);
this.name = name;
this.sku = sku;
this.rfid = rfid;
this.price = price;
}
}Typically this ProductState would be held by the Aggregate ProductActor, where the actor implements the Product protocol.
In recent years object storage has been managed by a technique known as object-relational mapping (ORM), where objects are disassembled to fit into the relational table, row, and column structures. In such cases SQL expressions are used to create, read, update, and delete such objects. Using Java means that the SQL operations will be managed using JDBC, but will often employ a mapping layer on top of that. Some well-known ORM tools are TopLink/EclipseLink, Hibernate, various implementations of JPA, and others, such as Cayenne. There are other abstractions, such as Jdbi, that are not classified as an ORM, but provide worthy querying and mapping techniques that are much less invasive than ORM tools. All of these are or can be supported by a XOOM Symbio ObjectStore implementation.
Additionally, there is a XOOM Symbio ObjectStore implementation for Apache Geode. Apache Geode is an in-memory data fabric, compute grid, and distributed cache, which can hold object states.
Object Persistence Protocols
The ObjectStore protocol extends ObjectStoreReader and ObjectStoreWriter, defining a single message type in addition: close().
First consider the ObjectStoreWriter. It is composed of a number of variations of persist() and persistAll() message types, with differences being in the number of parameters supported in each. The richest form of the two message types follow.
As noted, there are variations of these two message types that have less parameters, providing defaults to the richer message types in their implementations. The full complement of parameters and types are described next.
Parameter
Description
T persistentObject
T is a subclass of PersistentObject, which has two attributes: long persistenceId and long version, and serves as the means to persist the corresponding object with a primary key of persistenceIdand a version indicating how many times the object has be modified.
Collection<T> persistentObjects
The same as T persistentObject, but as a collection of one or more.
List<Source<E>> sources
The List of Source instances, which are concrete subclasses of DomainEvent, Command, or ProcessMessage (see XOOM Lattice for details).
Metadata metadata
The metadata to associate with the stored data.
long updateId
The identity indicating that this persistence operation is considered an update of one or more previously read objects, or -1L if it is a creation, not an update, operation. A non-negative updateId will have been provided with the result of a read query. See QueryExpression and its QueryMode, which will be either ReadOnly or ReadUpdate.
PersistResultInterest interest
A protocol backed by an Actor that will receive indication of the results following the persistence operation. During tests this protocol may be mocked as a plain object, but must be designed for concurrent access (see AccessSafely). See below for the definition of this protocol.
Object object
An object that will be sent along with the PersistResultInterest. It may be nullor a valid instance of any application (or service) defined type.
When using ObjectStoreWriter, the sender must provide an Actor or mocked test object that implements the PersistResultInterestprotocol.
Next consider the ObjectStoreReader protocol. It provides a number of query methods, with variations on required and optional parameters.
The difference between the two types of methods is the number of objects that should be included in the query results, either one or a one-or-more result.
Parameter
Description
QueryExpression expression
The expression used to resolve the query. See below for the definition of this protocol.
QueryResultInterest interest
A protocol backed by an Actor that will receive indication of the results following the query operation. During tests this protocol may be mocked as a plain object, but must be designed for concurrent access (see AccessSafely). See below for the definition of this protocol.
Object object
An object that will be sent along with the QueryResultInterest. It may be nullor a valid instance of any application (or service) defined type.
The QueryExpression is defined as follows. There are two extensions of the basic QueryExpression, which are ListQueryExpression and MapQueryExpression.
These class definitions include a number of factory methods for conveniently and expressively creating new instances of each.
The difference between these three query expression types is how parameters are supplied at runtime. The plain QueryExpression is a single parameterless expression. The parameters of a ListQueryExpression are ordered for setting as positional parameters 1, 2, 3, etc., or as a list of comma delimited parameters. The MapQueryExpression parameters are named using the String map keys, with the corresponding values to be set in the query expression, such as expression target :id matched with key "id" and value "8d8acfe97a".
When using ObjectStoreReader, the sender must provide an Actor or mocked test object that implements the QueryResultInterestprotocol.
When the receiver is informed of a query result, it is expressed as either a multiple All result or a single Object result. Note that the Outcome may be a StorageException or a successful Result. The QueryMultiResults holds a collection of resulting objects and QuerySingleResult holds a single object result.
ObjectStore Implementations
There are a number of implementations of the ObjectStore.
Component: xoom-symbio
xoom-symbioYou may use the in-memory implementation for testing.
Component: xoom-symbio-geode
xoom-symbio-geodeThis is the implementation of the ObjectStore for Apache Geode.
Component: xoom-symbio-jdbc
xoom-symbio-jdbcThese depend on specific database mechanisms, such as PostgreSQL, MySQL, MariaDB, and HSQLDB.
Last updated