I recently learned about the Event Sourcing (and CQRS) design patterns. Unfortunately, reading through Martin Fowler’s bliki definition just didn’t help. What helped the most were two things:
CQRS relies on Event Sourcing in order to work.
Event Sourcing requires the following:
- You have an event store in which you store events.
- You have Aggregate Roots, which is a way of structuring data structures so that you can always link the fields and attributes and other associated data with the underlying “root” data structure. For example, the ‘pages’ in a ‘book’ would never change without the ‘book’ data structure knowing that.
Event Sourcing means that every time you change any data — any state, in fact, which also happens to be data — you generate an event.
Matt’s contact manager example application does just that: in all of the methods which change any data, an event is 1. created, 2. filled with the new data, and 3. added to the event store. It’s a little more complicated than that, but only because you also have to take into account the transactional logic necessary when changing data or state.
What’ s interesting about this is that you can then recreate state by “replaying” the events — from the beginning, if you have to. Replaying the events means that all of the incremental changes made are then reapplied after which you get your current state back!
CQRS is a design pattern that makes distributed and concurrent systems easier to design and maintain. The diagram above illustrates the problem particularly well: The user decides what she wants, resulting in a change being acted out on the state. That change then is also translated into an event which updates the report, which the user can then query if she’s curious.
By separating your “write” data model from your “read” data model you can respond to queries much more quickly and you can also make sure to use costly database transactions for operations that need it, for example. You do then run the risk that the data you query is not 100% accurate with regards to when it was queried: your “read” data model is always updated after your “write” data model.
Why am I writing about this? Well, CQRS certainly doesn’t really apply to my work, but Event Sourcing does. Being able to rewind (and re-forward) state is something that I think a BPM engine should do. I’m also curious if Event Sourcing could help when architecting any BPM engines that deal with ACM.
I’m waiting for eclipse to start up again, so I’ll post a quick note about the JTA manager lookup mechanism that’s changed in Hibernate 4 and AS7.
Those of you who’ve read the How do I migrate my application from AS5 or AS6 to AS7 guide on the Jboss AS 7 documentation site have probably come across the following quote:
Configure the datasource for Hibernate or JPA
If your application uses JPA and currently bundles the Hibernate JARs, you may want to use the Hibernate that is included with AS7. You should remove the Hibernate jars from your application. You should also remove the “hibernate.transaction.manager_lookup_class” property from your persistence.xml as this is not needed.
Unfortunately, while you may not need the
hibernate.transaction.manager_lookup_class property, you do need a property apparently.
If you don’t set any property (with regards to a JTA transaction manager), you’ll end up getting a stack trace that looks like this:
java.lang.NullPointerException at org.hibernate.engine.transaction.internal.jta.JtaStatusHelper.getStatus(JtaStatusHelper.java:73) at org.hibernate.engine.transaction.internal.jta.JtaStatusHelper.isActive(JtaStatusHelper.java:115) at org.hibernate.engine.transaction.internal.jta.CMTTransaction.join(CMTTransaction.java:149) at org.hibernate.ejb.AbstractEntityManagerImpl.joinTransaction(AbstractEntityManagerImpl.java:1208)
If you even go as far as googling the above stack trace, you’ll run into HHH-7109, which then mentions the
hibernate.transaction.jta.platform. Oh, except that it’s a new, undocumented property”. Great..
There is in fact, a whole chapter on transactions, for developers, here.
One of the problems with running jBPM on jBoss AS7 was that there was a fair amount of (re)configuration necessary to get everything working.
This was enough of a problem that me and Maciej worked together last week to create assembly files (which are used by the mvn-assembly-plugin) which will create wars that will run on EE6 servers, with an emphasis on AS7 of course.
The main changes are as follows:
- The persistence configurations for jBPM are JPA 1 — in the EE6 jars, we’ve added JPA 2 based persistence configurations for both the human-task war and the jbpm-console (server) war.
- The Hibernate 3 dependencies have been eliminated from the EE6 wars — in fact, there are no Hibernate (or other ORM) dependencies in the war. That works well with AS7, but may prove a problem with other EE 6 application servers (glassfish, websphere). I think that once the Hibernate 4 framework goes through another couple versions and is stabler, we can then add those dependencies into the wars in order to make sure that those wars work on all possible application servers.
- Unfortunately, Hibernate 3 has a lot of transitive dependencies that were also being included in the wars — mostly dependencies that were introduced via the dom4j dependency. These dependencies were also removed from the EE6 jars.
The new wars have the same name as the “normal” Java EE 5 wars, except that they have “EE6” as the maven classifier. That means that their names are something similar to the following: