An extension to LiquidProjections that uses NHibernate for storing projections.
Switch branches/tags
Nothing to show
Clone or download
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
.vs/LiquidProjections.NHibernate/v15/sqlite3 Allow writing additional info with the projector state. (#6) Sep 27, 2017
Build Initial move of the NHibernate project from the core project. May 6, 2017
Lib Initial move of the NHibernate project from the core project. May 6, 2017
Samples/ExampleHost
Src/LiquidProjections.NHibernate Allow only persisting the state of the projector when a batch actuall… Jul 28, 2018
Tests/LiquidProjections.NHibernate.Specs Allow only persisting the state of the projector when a batch actuall… Jul 28, 2018
.gitattributes Initial move of the NHibernate project from the core project. May 6, 2017
.gitignore Allow writing additional info with the projector state. (#6) Sep 27, 2017
LiquidProjections.NHibernate.sln [New] Added an example program demonstrating several features of the … Apr 19, 2018
LiquidProjections.NHibernate.sln.DotSettings [Breaking] Added support for LiquidProjections 3.0.0 Apr 17, 2018
LiquidProjections.NHibernate.v3.ncrunchsolution
NuGet.Config Initial move of the NHibernate project from the core project. May 6, 2017
README.MD [New] Added an example program demonstrating several features of the … Apr 19, 2018
SharedAssemblyInfo.cs Initial move of the NHibernate project from the core project. May 6, 2017
build.cake Initial move of the NHibernate project from the core project. May 6, 2017
build.ps1

README.MD

Liquid Projections for NHibernate Build status

What is this?

This package provides an NHibernateProjector that allows you to build NHibernate-backed projectors for use with LiquidProjections' event mapping API and Dispatcher class.

What does it offer?

  • Supports NHibernate 4.0 or later.
  • Allows customizing how many LiquidProjections Transactions it should process in a single database transaction.
  • Supports nesting one or more NHibernateChildProjectors that can be used for maintaining lookup tables and which are part of the same database transaction as the parent projector creates.
  • Ensures autonomy by storing the IProjectionState (e.g. the last transaction checkpoint) in the same transaction as the actual projection data.
  • Allows the projector to be configured with an ExceptionPolicy delegate so that you can handle projection exceptions and get full control on whether or not the projector should retry the entire batch, individual transactions, ignore or abort the exception.
  • If the implementation of IProjectorState has additional custom properties, you can use the EnrichState delegate of the NHibernateProjector to update the state object before it is written to the database. This is called as part of the same database transaction that encompasses the projector code.

Why would I use NHibernate for something like a projection

Some have argued that using raw SQL is the fasted method for updating RDBMS-backed projections. And quite often this is true. But depending on the nature of the projection, in particular when it touches the same projection many times in the same batch of events, the unit-of-work (the ISession) can provide some significant speed improvements.

Caching support

This package provides a simple caching mechanism in the form of the IProjectionCache and ships with the LruProjectionCache based on the FluidCaching project. The IProjectionCache is meant for the most common scenarios and thus has some limitations:

  • If the projector performs database modifications directly on the NHibernate ISession, that projector must make sure the cache is updated or cleared accordingly.
  • The cache doesn't understand relationships where a projection refers to another projection maintained by the same projector. For instance, a projector that maintains a graph of parents and children, where a child is also a (direct or indirect) parent must use a more advanced type of caching.

If you need more advanced caching, please refer to NHibernate's Second Level Caching feature.

About the sample application?

You'll find a sample application under the Samples folder that tries to demonstrate a couple of aspect of using LiquidProjections such as event maps, exception handling and lookups in combination with NHibernate. It uses the JsonFileEventStore example implementation to feed a list of events serialized into the ExampleEvents.zip into the Dispatcher.

This dispatcher gets used by the CountsProjector to build a Sqlite-backed DocumentCountProjection (stored in the output directory under projections.db). Each projection record has a one-to-many relationship to the ValidityPeriod object to track when a document is valid or not. The projector also maintains a CountryLookup using a NHibernateChildProjector to map country codes to country names.

The CountsProjector also demonstrates how to employ the LruProjectionCache to speed up lookups and updates of recently updated projections. And finally, the projector uses a pretty extensive example on how to use the ExceptionResolution.RetryIndividual to trace down the transaction that is causing the (simulated) non-transient exception and mark that projection as corrupt. In then uses the Filter property of the NHibernateProjector to skip any successive attempts to update that corrupted projection.

To expose the data from this projection, the sample program will expose an HTTP API end-point served through the StatisticsController at route http://localhost:9000/api/Statistics/CountsPerState. For example, run a GET on this URL to get some counters:

http://localhost:9000/api/Statistics/CountsPerState?country=6DF7E2AC-6F06-420A-A0B5-14FB3865E850&kind=BypassOverrideCertificate

As all my open-source projects are written to be examples of proper coding conventions and Test Driven Development, also consider checking out the unit tests to learn how the many features work together.