<?xml version="1.0"?>
<rss version="2.0">
<channel>
  <title>The Kitchen in the Zoo - jpa tag</title>
  <link>http://blog.maxant.co.uk:80/pebble/tags/jpa/</link>
  <description>&lt;small&gt;A blog where Ant writes about anything he finds interesting! &lt;a href=&#039;http://www.linkedin.com/in/maxant&#039;&gt;&lt;font color=&#039;white&#039;&gt;Who is Ant?&lt;/font&gt;&lt;/a&gt;      &lt;a href=&#039;/pebble/pages/copyright.html&#039;&gt;&lt;font color=&#039;white&#039;&gt;Copyright 2005-2012 Ant Kutschera&lt;/font&gt;&lt;/a&gt;&lt;/small&gt;</description>
  <language>en</language>
  <copyright>Ant Kutschera</copyright>
  <lastBuildDate>Thu, 10 May 2012 20:07:00 GMT</lastBuildDate>
  <generator>Pebble (http://pebble.sourceforge.net)</generator>
  <docs>http://backend.userland.com/rss</docs>
  
  
  <item>
    <title>Persistent State Machine with Apache SCXML</title>
    <link>http://blog.maxant.co.uk:80/pebble/2010/08/26/1282857660000.html</link>
    
      
        <description>
          The source code for this blog article can be downloaded &lt;a href=&#039;/pebble/files/SCXMLDemo2.zip&#039;&gt;here&lt;/a&gt;.&lt;br&gt;
&lt;br&gt;
I&#039;m bored of reinventing the wheel.  Everytime I need a state machine to ensure my states traverse only valid transitions, I find myself either not bothering, because I trust my coding (and write all the necessary unit tests of course), or writing very similar code over again.&lt;br&gt;
&lt;br&gt;
So I started wondering if there was a configurable state machine out there somewhere, and in no time at all Google gave me a link to &lt;a target=&#039;blank&#039; href=&#039;http://commons.apache.org/scxml/&#039;&gt;SCXML from Apache&lt;/a&gt;.  Apache SCXML is an implementation of a configurable state machine based on the &lt;a target=&#039;_blank&#039; href=&#039;http://www.w3.org/TR/scxml/&#039;&gt;SCXML working draft&lt;/a&gt; from W3C.&lt;br&gt;
&lt;br&gt;
I started by taking a look at what it does and how it works, always keeping in mind my requirements based on previous projects.  The main question was how I could use a state machine in a persistent entity so that when an attempt is made to change the state, the state machine validated the attempt, ensuring only valid transitions are carried out.  That meant two things:&lt;br&gt;
&lt;ul&gt;
	&lt;li&gt;The state machine had to be able to have its current state set to any state.  If I load an object
		with state out of the database, I need to be able to set that state in the state machine so that 
		it checks any attempts to change state, based on this starting state.&lt;/li&gt;
	&lt;li&gt;The state machine had to fit into a JPA entity class so that I could persist and load the state.&lt;/li&gt;
&lt;/ul&gt;
&lt;br&gt;
Apache SCXML doesn&#039;t come with great documentation but if you look around, it has some &#034;use cases&#034; which are examples of how you can use it.  It comes with the class org.apache.commons.scxml.env.AbstractStateMachine which uses reflection to trigger transitions.  I went for a slightly different approach and created the uk.co.maxant.demo.scxml.util.AbstractStateMachine, which wraps an instance of the SCXMLExecutor (the &#034;engine&#034;, or state machine itself).  By wrapping the state machine, I am able to provide two extra benefits:&lt;br&gt;
&lt;ul&gt;
	&lt;li&gt;I can construct the state machine using the starting state out of a persisted entity, rather than 
		being forced to use the state charts initial state.  The implementation details of this construction 
		are a little complicated so my abstract wrapper can hide the details from the caller who is more
		interested in writing some business code, rather than boiler plate code.&lt;/li&gt;
	&lt;li&gt;I can enforce only valid state transitions, in that before performing a transition, I can use the
		state machine to check if its a valid transition from the current state.  Apache SCXMLs default 
		handling means that if you try to set the state to an illegal state, the state machine simply does
		nothing.  I prefer to be a little harsher and throw an IllegalStateException!&lt;/li&gt;
&lt;/ul&gt;
&lt;br&gt;
The implementation of the AbstractStateMachine contains trigger methods for changing state via transition events.  Each event makes a simple call to the &lt;code&gt;AbstractStateMachine.trigger(String)&lt;/code&gt; method which first of all checks that the current state allows the transition, and second of all delegates the transition to the wrapped state machine instance.  If the requested state transition is illegal, then an &lt;code&gt;IllegalStateException&lt;/code&gt; with details of the problem is thrown.  I too, could have also used reflection like the Apache example, but prefer to write more readable code for this Blog.&lt;br&gt;
&lt;br&gt;
Apache SCXML is built up by creating an &lt;code&gt;SCXML&lt;/code&gt; instance which is based upon the configuration which is an XML representation of the state chart and can be generated from UML.  As such, this configuration has an initial state, as defined in your state chart.  You then create an instance of the engine (state machine, &lt;code&gt;SCXMLExecutor&lt;/code&gt;) which is responsible for running with the configuration.  For performance reasons, the configuration should only be created once, as it parses the XML document.  In my demo, I instantiated it at class load time in the subclass of &lt;code&gt;AbstractStateMachine&lt;/code&gt;.&lt;br&gt;
&lt;br&gt;
So what do you do, if you are loading an object from a persistent store like a database and you want to instantiate your state machine (&lt;code&gt;SCXMLExecutor&lt;/code&gt;) with a state other than the initial state?  Well, it&#039;s quite easy, you simply use the API to modify the current state of the state machine (&lt;code&gt;SCXMLExecutor&lt;/code&gt;) instance and set the initial state to be that, which your persisted entity currently has.  The method isn&#039;t &lt;code&gt;setCurrentState()&lt;/code&gt;, rather you use the current state object, and remove its states and set the relevant state which you retrieved from the configuration (&lt;code&gt;SCXML&lt;/code&gt;).  Have a look at &lt;code&gt;AbstractStateMachine.setInitialState(SCXMLExecutor, String)&lt;/code&gt; to see how.  Thanks to the SCXML team for showing me how to do this!&lt;br&gt;
&lt;br&gt;
So having done all that, I was now in a position to use the state machine to manage the state in a persistent entity.  I created a database table with a &lt;code&gt;varchar&lt;/code&gt; column for holding my state, and primary key.  In the real world, the state would be part of a much larger entity with other fields.  I then setup my Eclipse project to contain the JPA facet and by right clicking on the project was able to generate my JPA entity classes from the table, such as shown in the &lt;code&gt;SomethingPersistentWithState&lt;/code&gt; class.  The only special thing I did, was to select &#034;property based access&#034; as the way in which JPA accesses the attributes.  Normally, and by default, JPA uses field based access, i.e. it uses reflection at runtime to get and set the class attributes.  By selecting &#034;property based access&#034;, Eclipse generates an additional Annotation on my entity class: &lt;code&gt;@Access(AccessType.PROPERTY)&lt;/code&gt;.  I then had only three things to do:&lt;br&gt;
&lt;ul&gt;
	&lt;li&gt;Change the &#034;state&#034; class attribute from a &lt;code&gt;String&lt;/code&gt; into an instance of
		&lt;code&gt;StateMachineDemo&lt;/code&gt;, which is the implementation of &lt;code&gt;AbstractStateMachine&lt;/code&gt;.
		I can do this, because the above Annotation means that JPA doesn&#039;t care how I implement the 
		attribute, is will always use bean conform accessors to set/get the state of my entity, namely the
		&lt;code&gt;String getState()&lt;/code&gt; and &lt;code&gt;void setState(String)&lt;/code&gt; methods.&lt;/li&gt;
	&lt;li&gt;Change the generated &lt;code&gt;void setState(String)&lt;/code&gt; method visibility to become private, so
		that no one could explicitly set the state of my entity.  The method needs to exist, so that JPA can 
		access the attribute to persist it, but JPA can happily live with the method being private.&lt;/li&gt;
	&lt;li&gt;Add methods for each transition, which simply delegate the call to the state machine.  Users of the 
		persistent entity use these trigger methods to change the state, rather than calling
		&lt;code&gt;void setState(String)&lt;/code&gt; on the entity.&lt;/li&gt;
&lt;/ul&gt;
&lt;br&gt;
These changes are all shown/documented in the &lt;code&gt;StateMachineDemo&lt;/code&gt; class.&lt;br&gt;
&lt;br&gt;
To demonstrate the state machine working, as well as it being used in a persistent environment, have a look at the JUnit test case &lt;code&gt;StateMachineDemoTest&lt;/code&gt;.  This class contains tests for setting any state during construction, tests for state transitions proving that only valid ones are allowed, as well as reading/writing an entity containing state to the database and updating the state along the way.
&lt;br&gt;
&lt;br&gt;
Download the source &lt;a href=&#039;/pebble/files/SCXMLDemo2.zip&#039;&gt;here&lt;/a&gt;.&lt;br&gt;
&lt;br&gt;
&amp;copy; 2010, Ant Kutschera&lt;div class=&#034;tags&#034;&gt;&lt;span&gt;Social Bookmarks : &lt;/span&gt;&amp;nbsp;&lt;a href=&#034;http://slashdot.org/bookmark.pl?url=http://blog.maxant.co.uk:80/pebble/2010/08/26/1282857660000.html&amp;amp;title=Persistent+State+Machine+with+Apache+SCXML&#034; target=&#034;_blank&#034; title=&#034;Add this post to Slash Dot&#034;&gt;&lt;img src=&#034;common/images/slashdot.png&#034; alt=&#034;Add this post to Slashdot&#034; border=&#034;0&#034; /&gt;&lt;/a&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;a href=&#034;http://digg.com/submit?url=http://blog.maxant.co.uk:80/pebble/2010/08/26/1282857660000.html&amp;amp;title=Persistent+State+Machine+with+Apache+SCXML&#034; target=&#034;_blank&#034; title=&#034;Digg this post&#034;&gt;&lt;img src=&#034;common/images/digg.png&#034; alt=&#034;Add this post to Digg&#034; border=&#034;0&#034; /&gt;&lt;/a&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;a href=&#034;http://reddit.com/submit?url=http://blog.maxant.co.uk:80/pebble/2010/08/26/1282857660000.html&amp;amp;title=Persistent+State+Machine+with+Apache+SCXML&#034; target=&#034;_blank&#034; title=&#034;Add this post to Reddit&#034;&gt;&lt;img src=&#034;common/images/reddit.png&#034; alt=&#034;Add this post to Reddit&#034; border=&#034;0&#034; /&gt;&lt;/a&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;a href=&#034;http://del.icio.us/post?url=http://blog.maxant.co.uk:80/pebble/2010/08/26/1282857660000.html&amp;amp;title=Persistent+State+Machine+with+Apache+SCXML&#034; target=&#034;_blank&#034; title=&#034;Save this post to Del.icio.us&#034;&gt;&lt;img src=&#034;common/images/delicious.png&#034; alt=&#034;Add this post to Delicious&#034; border=&#034;0&#034; /&gt;&lt;/a&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;a href=&#034;http://www.stumbleupon.com/submit?url=http://blog.maxant.co.uk:80/pebble/2010/08/26/1282857660000.html&amp;amp;title=Persistent+State+Machine+with+Apache+SCXML&#034; target=&#034;_blank&#034; title=&#034;Stumble this post&#034;&gt;&lt;img src=&#034;common/images/stumbleupon.png&#034; alt=&#034;Add this post to Stumble it&#034; border=&#034;0&#034; /&gt;&lt;/a&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;a href=&#034;http://www.google.com/bookmarks/mark?op=edit&amp;amp;bkmk=http://blog.maxant.co.uk:80/pebble/2010/08/26/1282857660000.html&amp;amp;title=Persistent+State+Machine+with+Apache+SCXML&#034; target=&#034;_blank&#034; title=&#034;Add this post to Google&#034;&gt;&lt;img src=&#034;common/images/google.png&#034; alt=&#034;Add this post to Google&#034; border=&#034;0&#034; /&gt;&lt;/a&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;a href=&#034;http://technorati.com/faves?add=http://blog.maxant.co.uk:80/pebble/2010/08/26/1282857660000.html&#034; target=&#034;_blank&#034; title=&#034;Add this post to Technorati&#034;&gt;&lt;img src=&#034;common/images/technorati.png&#034; alt=&#034;Add this post to Technorati&#034; border=&#034;0&#034; /&gt;&lt;/a&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;a href=&#034;http://www.bloglines.com/sub/http://blog.maxant.co.uk:80/pebble/2010/08/26/1282857660000.html&#034; target=&#034;_blank&#034; title=&#034;Add this post to Bloglines&#034;&gt;&lt;img src=&#034;common/images/bloglines.png&#034; alt=&#034;Add this post to Bloglines&#034; border=&#034;0&#034; /&gt;&lt;/a&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;a href=&#034;http://www.facebook.com/share.php?u=http://blog.maxant.co.uk:80/pebble/2010/08/26/1282857660000.html&#034; target=&#034;_blank&#034; title=&#034;Add this post to Facebook&#034;&gt;&lt;img src=&#034;common/images/facebook.png&#034; alt=&#034;Add this post to Facebook&#034; border=&#034;0&#034; /&gt;&lt;/a&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;a href=&#034;http://www.furl.net/storeIt.jsp?u=http://blog.maxant.co.uk:80/pebble/2010/08/26/1282857660000.html&amp;amp;t=Persistent+State+Machine+with+Apache+SCXML&#034; target=&#034;_blank&#034; title=&#034;Add this post to Furl&#034;&gt;&lt;img src=&#034;common/images/furl.png&#034; alt=&#034;Add this post to Furl&#034; border=&#034;0&#034; /&gt;&lt;/a&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;a href=&#034;https://favorites.live.com/quickadd.aspx?mkt=en-us&amp;amp;url=http://blog.maxant.co.uk:80/pebble/2010/08/26/1282857660000.html&amp;amp;title=Persistent+State+Machine+with+Apache+SCXML&#034; target=&#034;_blank&#034; title=&#034;Add this post to Windows Live&#034;&gt;&lt;img src=&#034;common/images/windowslive.png&#034; alt=&#034;Add this post to Windows Live&#034; border=&#034;0&#034; /&gt;&lt;/a&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;a href=&#034;http://bookmarks.yahoo.com/toolbar/savebm?opener=tb&amp;amp;u=http://blog.maxant.co.uk:80/pebble/2010/08/26/1282857660000.html&amp;amp;t=Persistent+State+Machine+with+Apache+SCXML&#034; target=&#034;_blank&#034; title=&#034;Add this post to Yahoo!&#034;&gt;&lt;img src=&#034;common/images/yahoo.png&#034; alt=&#034;Add this post to Yahoo!&#034; border=&#034;0&#034; /&gt;&lt;/a&gt;&lt;/div&gt;
        </description>
      
      
    
    
    
    <comments>http://blog.maxant.co.uk:80/pebble/2010/08/26/1282857660000.html#comments</comments>
    <guid isPermaLink="true">http://blog.maxant.co.uk:80/pebble/2010/08/26/1282857660000.html</guid>
    <pubDate>Thu, 26 Aug 2010 21:21:00 GMT</pubDate>
  </item>
  
  </channel>
</rss>

