Package org.projectbarbel.histo
Interface BarbelHisto<T>
-
- Type Parameters:
T
- the type to manage
- All Known Implementing Classes:
BarbelHistoCore
public interface BarbelHisto<T>
The main abstraction ofBarbelHisto
that provides the client API. Clients should perform all operations with this interface.
Create an instance as follows:
BarbelHisto histo = BarbelHistoBuilder.barbel().build();
ExploreBarbelHistoBuilder
documentation to learn about the different settings clients can choose.
BarbelHisto
tracks two time dimensions:
- effective time is when a change to a domain object is supposed to become effective
- record time is when that change was recorded in the system, when records were created and inactivated
To manage data withBarbelHisto
clients must annotate their classes withDocumentId
on the primary key. An example:public class SomeBusinessPojo {
The primary key should be business oriented, i.e. personnel number, contract number.@DocumentId
private String documentId; ... any custom fields and methods public String getDocumentId() { return documentId; } public void setDocumentId(String id) { this.documentId = id; } }
TwoBarbelMode
s can be used to manage different types of objects:BarbelMode.POJO
is the default mode. Of course, using POJO mode is the easiest way forward. However, behind the scenesBarbelHisto
uses proxying when managing POJOs to store the version data with the objects that clients save. Proxying can become complicated in some situations. For that reason there is another mode calledBarbelMode.BITEMPORAL
. One can change the mode toBarbelMode.BITEMPORAL
with theBarbelHistoBuilder.withMode(BarbelMode)
method like so:BarbelHisto barbel = BarbelHistoBuilder.barbel().withMode(BarbelMode.BITEMPORAL).build();
IfBarbelMode.BITEMPORAL
is used clients have to implement the interfaceBitemporal
on the type they wish to manage withBarbelHisto
. In this mode, there won't be any proxying magic applied to objects. When clients implement the interfaceBitemporal
they need to declare a field of typeBitemporalStamp
in the business object type. There is nothing else required than declaring the field. Anything else is managed byBarbelHisto
. SeeDefaultDocument
as an example of a fully equipped business class inBarbelMode.BITEMPORAL
.
In any mode clients never have to care about the bitemporal version stamp. This is completely managed byBarbelHisto
. Clients only need to take care that their primary key is properly set.
Use thesave(Object, ZonedDateTime, ZonedDateTime)
method to save objects toBarbelHisto
. The from/until period entered describes when the object data should become effective, and until it should be effective. Clients useEffectivePeriod.INFINITE
to express that the object stored is valid until infinite.
To retrieve data stored intoBarbelHisto
clients can useretrieveOne(Query)
orretrieve(Query)
. Use theBarbelQueries
for convenience like so:List result = core.retrieve(BarbelQueries.allActive(someBusinessPojo.getDocumentId()), BarbelQueryOptions.sortAscendingByEffectiveFrom());
Users should become familiar with all the queries inBarbelQueries
.
Clients that use custom data stores like MongoDB or any other of the kind should callunload(Object...)
after processing data withBarbelHisto
. To restore the journal later to continue bitemporal data processing useload(Collection)
.
Usetimeshift(Object, ZonedDateTime)
to turn back time and see how document journals looked like in the past. Time shift is one of the core functionalities ofBarbelHisto
. Clients can turn back time to see how the document journals for a document Id looked like at that given time. This knowledge is mission critical for many businesses. Notice that this method returns complete journals of a given document Id. It is often the case that objects effective periods change over time as updates are posted toBarbelHisto
with different effective periods. Today a document may have two active effective periods, one period A starting two years ago, and another one period B effective beginning in two weeks, e.g. an adress change to an initial client record that the client communicated two weeks ago.Today: 2019-02-01 Effective from Effective Until Created at Adress 2017-01-01 2019-02-14 2016-12-15 Barbel-Street 1 Period A 2019-02-14 Infinite 2019-01-15 Carp-Street 10 Period B
In this example three weeks ago on January 9, 2019 that adress change in question was not recorded to the system. If you turn back time to January 9, 2019 that journal returned by time shift would only contain the effective period A. These cases can get more complex obviously the more updates are posted for a given document Id. UseprettyPrintJournal(Object)
to get more familiar with effective periods and record time.
- Author:
- Niklas Schlimm
-
-
Method Summary
All Methods Instance Methods Abstract Methods Default Methods Modifier and Type Method Description boolean
contains(Object documentId)
Check ifBarbelHisto
contains data for the given document ID.void
load(Collection<Bitemporal> bitemporals)
Method for clients that use a custom data store.String
prettyPrintJournal(Object id)
Pretty print the journal for the given document ID.List<T>
retrieve(com.googlecode.cqengine.query.Query<T> query)
Retrieve data fromBarbelHisto
using cqengine like queries.List<T>
retrieve(com.googlecode.cqengine.query.Query<T> query, com.googlecode.cqengine.query.option.QueryOptions options)
Retrieve data fromBarbelHisto
using cqengine like queries.T
retrieveOne(com.googlecode.cqengine.query.Query<T> query)
Retrieve data fromBarbelHisto
using cqengine like queries.T
retrieveOne(com.googlecode.cqengine.query.Query<T> query, com.googlecode.cqengine.query.option.QueryOptions options)
Retrieve data fromBarbelHisto
using cqengine like queries.default BitemporalUpdate<T>
save(T newVersion)
Save objects toBarbelHisto
.default BitemporalUpdate<T>
save(T newVersion, ZonedDateTime from)
Save objects toBarbelHisto
.BitemporalUpdate<T>
save(T newVersion, ZonedDateTime from, ZonedDateTime until)
Save objects toBarbelHisto
.default BitemporalUpdate<T>
save(T newVersion, EffectivePeriod period)
Save objects toBarbelHisto
.DocumentJournal
timeshift(Object id, ZonedDateTime time)
Turn back time to see how document journals looked like in the past.Collection<Bitemporal>
unload(Object... documentIDs)
Unloads the journal data of the given document IDs into a collection and return that to the client.
-
-
-
Method Detail
-
save
BitemporalUpdate<T> save(T newVersion, ZonedDateTime from, ZonedDateTime until)
Save objects toBarbelHisto
. Creates snapshots of state. Clients can safely continue to work on passed instances. Thread safe, applies lock to journals of document IDs (not the complete backbone). This allows concurrent work on different document IDs. If clients try to update the same document Id, this method throwsConcurrentModificationException
. The method returns a copy of the object saved including the version data. In inBarbelMode.POJO
cast the returned object toBitemporal
to read the version data.- Parameters:
newVersion
- the object state to savefrom
- effective time of object stateuntil
- effective until of the state- Returns:
- the
BitemporalUpdate
performed by this save operation
-
save
default BitemporalUpdate<T> save(T newVersion, EffectivePeriod period)
Save objects toBarbelHisto
. Creates snapshots of state. Clients can safely continue to work on passed instances. Thread safe, applies lock to journals of document IDs (not the complete backbone). This allows concurrent work on different document IDs. If clients try to update the same document Id, this method throwsConcurrentModificationException
. The method returns a copy of the object saved including the version data. In inBarbelMode.POJO
cast the returned object toBitemporal
to read the version data.- Parameters:
newVersion
- the object state to saveperiod
- effective time period of object state- Returns:
- the
BitemporalUpdate
performed by this save operation
-
save
default BitemporalUpdate<T> save(T newVersion, ZonedDateTime from)
Save objects toBarbelHisto
. Creates snapshots of state. Clients can safely continue to work on passed instances. Thread safe, applies lock to journals of document IDs (not the complete backbone). This allows concurrent work on different document IDs. If clients try to update the same document Id, this method throwsConcurrentModificationException
. The method returns a copy of the object saved including the version data. In inBarbelMode.POJO
cast the returned object toBitemporal
to read the version data. This method assumes that the object is effective infinitely, starting from the provided from-Date.- Parameters:
newVersion
- the object state to savefrom
- effective time of object state- Returns:
- the
BitemporalUpdate
performed by this save operation
-
save
default BitemporalUpdate<T> save(T newVersion)
Save objects toBarbelHisto
. Creates snapshots of state. Clients can safely continue to work on passed instances. Thread safe, applies lock to journals of document IDs (not the complete backbone). This allows concurrent work on different document IDs. If clients try to update the same document Id, this method throwsConcurrentModificationException
. The method returns a copy of the object saved including the version data. In inBarbelMode.POJO
cast the returned object toBitemporal
to read the version data. This method assumes that the object is effective from now to infinity.- Parameters:
newVersion
- the object state to save- Returns:
- the
BitemporalUpdate
performed by this save operation
-
retrieve
List<T> retrieve(com.googlecode.cqengine.query.Query<T> query)
Retrieve data fromBarbelHisto
using cqengine like queries. Clients want to useBarbelQueries
for there convenience here.BarbelQueries
can be combined with additional queries fromQueryFactory
.- Parameters:
query
- the client query fromBarbelQueries
and/orQueryFactory
- Returns:
- the copies returned, maybe empty, never null
-
retrieve
List<T> retrieve(com.googlecode.cqengine.query.Query<T> query, com.googlecode.cqengine.query.option.QueryOptions options)
Retrieve data fromBarbelHisto
using cqengine like queries. Clients want to useBarbelQueries
andBarbelQueryOptions
for there convenience here.BarbelQueries
can be combined with additional queries fromQueryFactory
.- Parameters:
query
- the client query fromBarbelQueries
and/orQueryFactory
options
- the options fromBarbelQueryOptions
orQueryFactory
- Returns:
- the copies returned, maybe empty, never null
-
retrieveOne
T retrieveOne(com.googlecode.cqengine.query.Query<T> query)
Retrieve data fromBarbelHisto
using cqengine like queries. Clients want to useBarbelQueries
for there convenience here.BarbelQueries
can be combined with additional queries fromQueryFactory
. ThrowsIllegalStateException
when query returns more then one result,NoSuchElementException
if nothing was found.- Parameters:
query
- the client query fromBarbelQueries
and/orQueryFactory
- Returns:
- the returned copy
-
retrieveOne
T retrieveOne(com.googlecode.cqengine.query.Query<T> query, com.googlecode.cqengine.query.option.QueryOptions options)
Retrieve data fromBarbelHisto
using cqengine like queries. Clients want to useBarbelQueries
andBarbelQueryOptions
for there convenience here.BarbelQueries
can be combined with additional queries fromQueryFactory
. ThrowsIllegalStateException
when query returns more then one result,NoSuchElementException
if nothing was found.- Parameters:
query
- the client query fromBarbelQueries
and/orQueryFactory
options
- the options fromBarbelQueryOptions
orQueryFactory
- Returns:
- the returned copy
-
timeshift
DocumentJournal timeshift(Object id, ZonedDateTime time)
Turn back time to see how document journals looked like in the past. If clients passLocalDateTime.now()
the actual journal is returned. Time shift does not change the backbone collection of theBarbelHisto
instance, instead it returns an instance ofDocumentJournal
with copies of managedBitemporal
objects.- Parameters:
id
- the document Idtime
- the time, must be in the past- Returns:
- the document journal at that given time
-
prettyPrintJournal
String prettyPrintJournal(Object id)
Pretty print the journal for the given document ID.- Parameters:
id
- the document ID- Returns:
- the journal as pretty print out
-
load
void load(Collection<Bitemporal> bitemporals)
Method for clients that use a custom data store. Only add complete set of versions for one or more document IDs. Usually used in conjunction withunload(Object...)
.
InBarbelMode.POJO
(default) clients have to pass a collection ofBitemporalVersion
. InBarbelMode.BITEMPORAL
mode clients can add objects that implementBitemporal
.
- Parameters:
bitemporals
- consistent list ofBitemporal
versions- See Also:
- https://github.com/npgall/cqengine
-
unload
Collection<Bitemporal> unload(Object... documentIDs)
Unloads the journal data of the given document IDs into a collection and return that to the client. The journal data of the given document IDs will be deleted from the backbone. This method is used when client uses custom data store. Clients may store the returned collection to the data store of their choice. Used in conjunction withload(Collection)
to re-load that stored journals back intoBarbelHisto
to continue bitemporal processing.
InBarbelMode.POJO
(default) clients receive a collection ofBitemporalVersion
objects. InBarbelMode.BITEMPORAL
clients receive objects that implementBitemporal
.
- Parameters:
documentIDs
- the document IDs to unload- Returns:
- the collection of
Bitemporal
objects to store into an arbitrary data store - See Also:
- https://github.com/npgall/cqengine
-
contains
boolean contains(Object documentId)
Check ifBarbelHisto
contains data for the given document ID.- Parameters:
documentId
- the document id to check- Returns:
- true if
BarbelHisto
contains data otherwise false
-
-