How to build a object back along with it's entire nesting using just the snapshots available in javers? - javers

I have a deeply nested object and I am changing one of properties inside the nesting, when I audit it with Javers it fragments the object and stores it in various snapshots. Now I want to build it back with all changes, so as to get the change and state of object at the time.

Shadows (see https://javers.org/documentation/jql-examples/#query-for-shadows) offer the most natural view on data history. Thanks to JaVers magic, you can see historical versions of your domain objects reconstructed from Snapshots.

Related

How do I map relations in an eventstore used in an eventsourced architecture?

I am trying to wrap my head around structuring relationships in an eventstore. I am all new at eventsourcing so please bear with me. :-)
How should relationships be mapped in an eventstore? Can you please give me some recommendations?
Imagine, I have a domain regarding project management. I have an aggregate which is a Project. The Project aggregate root contains Tasks, Documents, Files, Folders which are collections of core entities in the Project.
I also have a ProjectBranch which can be part of the Project aggregate but it could also be looked at independently. In the ProjectBranch the previously mentioned collections can be changed, and a ProjectBranch can be merged into the Project again which updates the collections of the Project.
Some of the flow resembles a VCS system.
How should these relations be mapped and which separation of aggregates and aggregate roots should I create?
If the Project is the only aggregate, the events (I imagine) look like the following:
ProjectWasCreated [aggregate]
ProjectDocumentWasCreated
ProjectTaskWasCreated
ProjectBranchWasCreated
ProjectBranchDocumentWasCreated
(how will this event e.g. know which branch the Document belongs to)
All events that happen in a ProjectBranch will in some way have to be replayed on the Project once the ProjectBranchWasMergedToProject event happens.
On the other hand there could be a more relational structure where there are several separate aggregates - e.g. Project, ProjectBranch, Task, Document and so on.
This would mean that the domain has a different set of events which could look like the following:
ProjectWasCreated [aggregate]
DocumentWasCreated [aggregate]
ProjectDocumentWasAttached(documentId)
ProjectBranchWasCreated(projectId) [aggregate]
DocumentWasCreated [aggregate]
ProjectBranchDocumentWasAttached(documentId)
Some of these functionalities might need to work independently outside of the Project, so they would be made as standalone modules.
Thanks :-)
Let's assume that all these elements are aggregates: Project, ProjectBranch, Task, Document, and so on.
One of the basic tenets of constructing Aggregates is that they form a transactional consistency boundary, meaning that within a single Aggregate, all elements must be consistent and satisfy associated business rules at the time of a transaction.
That is why people usually stick with small Aggregate structures, with most Aggregates having just one Entity within them. It is going to be impossible for you to keep all these elements in sync and consistent, as your Project grows.
Now onto your question, the answer to relationships is in two parts:
All linkages between Aggregates should be in the form of Aggregate identities. If a Task is linked to a Project, then the Task aggregate event will contain ProjectId as an attribute.
You should not store aggregate structures inside one another.
If you were using an RDBMS, any syncing required between aggregates (if a Project is closed, for example), should be accomplished with the help of Domain Events.
But since you are using EventSourcing, you don't need to do this in the background. You dynamically construct the aggregate structure, which brings us to the second point.
Like any other EventSource projection, when you construct an aggregate object, you will need to reconstitute the internal data elements.
If you want the Project structure to be available as part of your Task projection, you make a call to the Project Application Service to retrieve the Project Aggregate in realtime.
So on and so forth for all linked Aggregates that you may want as part of your projection.

Save only changes on JV_SNAPSHOT table instead of entire object for Audit

I'm trying to implement Javers for auditing my fairly complex object, and I love it so far. But when I see the database, entire snapshot is saved for my object which will eventually grow massive in my use case. Since I'm using Javers only to audit changes but not to restore object from snapshots, is there any way for me to store only changed properties on subsequent object commits?
There is no way to persist only a changed properties of an object. A snapshot is always a picture of a whole object. What I can advice, is to split your objects into smaller pieces (for example using ValueObject pattern). In this case, JaVers would save only snapshots of changed pieces (unchanged would be reused).
Other option is #DiffIgnore (see ignoring things).
Btw, how large are your objects, I mean how many properties they contain?

What is the differences between Session and Local (client-side only) Collection?

In Meteor, I have a little confusion between Session and Local Collection.
I know that Session is a temporary reactive key-value store, client-side only, and is cleaned on page refresh.
Local collection seems to be the same: reactive, temporary client-side storage, cleaned on page refresh with more flexible function like insert, update & remove query like server-side Mongo collection.
So I guess I could manage everything in Local Collection without Session, or, everything in Session without Local Collection.
But what is the best and efficient way to use Session and/or Local collection?
Simply, when to use Session and not use it?
And when to use Local collection and when not use it?
As I read your question I told myself that this is a very easy question, but then I was scratching my head. I tried to figure out an example that you can just accomplish with session or collections. But I didn't found any use-case. So let's rollup things from begin. Basically you already answered the question on your own, because it is the little sugar that makes collections something special.
When to use a collection?
Basically a collection is a database artifact. Imagine you have a client-server-application. All the data is persisted in the server side storage. Now you can use a local collection to provide the user a small subset of the servers collection. So a client collection is a database with reduced amount of data. The advantage is that you can access the collection with queries. You can use the same queries on server and client. In additon a collection always contains multiple objects of the same type. Sometimes you produce data on client for the client. No server interaction needed. Than you can use a local collection. A local collection provides the same functionality as a normal collection without server communication. This should be used if you have multiple objects with the same structure and in special if you'd like to use query operators.
You can also save the data inside a session object. Session objects can contain multiple objects as well. But imaging you want to find an object in an objectarray indexed with a special id. Than you need to iterate throw the whole array in order to find this object. You have to write additional logic, that can be handled with collection like magic. Further, collections return cursors. A cursor is an reactive object that just changes if the selected data changes. That means if you use find with an id. Than this object just rerenders when the object to this id changes. With session you can't. When a session changes you need to rerender all depending objects.
When to use a session?
For everything else. Sessions are often just small objects that contain some configuration logic. It is basically just one object and not a multiple occurency of equal objects. Haven't time now to go in detail but if it does not fit the collection use-cases you can use sessions.
Have a look at this post that describes why sessions should not be overused.
I assume that by local collection you mean: new Mongo.Collection(null)
The difference is that local collections do not survive hot code pushes. A refresh will erase Session, but hot code push will not, there's special code in Meteor to persist the values of the Session variable in the case of a hot code push..
You would use Session whenever you're storing temporary values that do NOT need to be persisted to the database.
Trivial examples could include a users selection of filters or the item in an index vies that is currently selected.
manipulated data in minimongo (insert, update, delete etc) is intended to be sent back to the server and stored in the database. For example this could be updating a users profile information etc.

Data Synchronization from Relational Database to Couch DB

I need to synchronize my Relational database(Oracle or Mysql) to CouchDb. Do anyone has any idea how its possible. if its possbile than how we can notify the CouchDb for any changes happened on the relational DB.
Thanks in advance.
First of all, you need to change the way you think about database modeling. Synchronizing to CouchDB is not just creating documents of all your tables, and pushing them to Couch.
I'm using CouchDB for a site in production, I'll describe what I did, maybe it will help you:
From the start, we have been using MySQL as our primary database. I had entities mapped out, including their relations. In an attempt to speed up the front-end I decided to use CouchDB as a content repository. The benefit was to have fully prepared documents, that contained all the relational data, so data could be fetched with much less overhead.
Because the documents can contain related entities - say a question document that contains all answers - I first decided what top-level entities I wanted to push to Couch. In my example, only questions would be pushed to Couch, and those documents would contain the answers, and possible some metadata, such as tags, user info, etc. When requesting a question on the frontend, I would only need to fetch one document to have all the information I need at that point.
Now for your second question: how to notify CouchDB of changes. In our case, all the changes in our data are done using a CMS. I have a single point in my code which all edit actions call. That's the place where I hooked in a function that persisted the object being saved to CouchDB. The function determines if this object needs persisting (ie: is it a top level entity), then creates a document of this object (think about some sort of toArray function), and fetches all its relations, recursively. The complete document is then pushed to CouchDB.
Now, in your case, the variables here may be completely different, but the basic idea is the same: figure out what documents you want saved, and how they look like. Then write a function that composes these documents and make sure this is called when changes are made to your relational database.
Notifying CouchDB of a change
CouchDB is very simple. Probably the easiest thing is directly updating an existing document. Two ways to implement this come to mind:
The easiest way is a normal CouchDB update: Fetch the current document by id; modify it; then send it back to Couch with HTTP PUT or POST.
If you have clear application-specific changes (e.g. "the views value was incremented") then writing an _update function seems prudent. Update function are very simple: they receive an HTTP query and a document; they modify the document; and then CouchDB stores the new version. You write update functions in Javascript and they run on the server. It is a great way to "compress" common actions into simpler (and fewer) HTTP queries.

Mapping Linq Entities and Domain Objects and object tracking

If I map my Domain objects to linq Entities will I now not be able to track changes when saving my domain objects? So for any change in my model that i wish to make, once I map the object to linq entities for submission to db, all object values will be submitted to the db by linq since it it goes through a mapping first? Or would the object tracking here still be utilized?
Depends on the O/R mapper you're using. You're referring to entity framework which doesn't do any change tracking inside the entity and therefore it needs help from you when you re-attach an entity which previously was fetched from the db (so it knows it's not new).
Here's an article from microsoft about CRUD operations in multi-tiered environments (similiar issues to your Domain mapping scenario).
Check out the Update - With Complete Entities for the way to do change tracking yourself.
There's another technique, where you attach the entity as unmodified, and then .Refresh() with Keep Current Values - replacing the original. This would allow you to Insert/Update/Do Nothing as appropriate at the cost of a database roundtrip.

Resources