<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>blog.smart-java.nl &#187; Tools/Frameworks</title>
	<atom:link href="http://blog.smart-java.nl/blog/index.php/category/toolsframeworks/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.smart-java.nl/blog</link>
	<description>Ordina J-Technologies - Java Blog</description>
	<lastBuildDate>Wed, 05 May 2010 20:06:33 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.1</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Running JPA (Hibernate3) and JTA on IBM Websphere 6.1 &amp; 7</title>
		<link>http://blog.smart-java.nl/blog/index.php/2010/05/05/jpa-hibernate3-jta-was7/</link>
		<comments>http://blog.smart-java.nl/blog/index.php/2010/05/05/jpa-hibernate3-jta-was7/#comments</comments>
		<pubDate>Wed, 05 May 2010 07:34:07 +0000</pubDate>
		<dc:creator>Vincent Lussenburg</dc:creator>
				<category><![CDATA[Java EE]]></category>
		<category><![CDATA[Object Relational Mapping]]></category>
		<category><![CDATA[Spring]]></category>

		<guid isPermaLink="false">http://blog.smart-java.nl/blog/?p=1100</guid>
		<description><![CDATA[Background
At my current project, we&#8217;re currently working on the second release of a webapp that integrates with a couple of webservices. It features a N+1 architecture (pretty much like the J-Technologies reference architecture) integrated by Spring 2.5.x. In this release, we have to persist into a single-consumer Oracle database. Since we have a tight deadline [...]]]></description>
			<content:encoded><![CDATA[<h2>Background</h2>
<p>At my current project, we&#8217;re currently working on the second release of a webapp that integrates with a couple of webservices. It features a N+1 architecture (pretty much like the J-Technologies reference architecture) integrated by Spring 2.5.x. In this release, we have to persist into a single-consumer Oracle database. Since we have a tight deadline but do want to experiment with various ORM implementations in the future, we ended up deciding to use JPA1.0 with Hibernate3 as persistence provider.</p>
<h2>Purpose of this post</h2>
<p>The combination Websphere / Hibernate / JPA did provide some &#8211; shall we say.. <em>challenges</em>? :&#41; You have some different approach routes to wire these technologies together and having a lot of choices can be confusing. The purpose of this post therefore is not only to show <em>how</em> we integrated it all but also <em>why</em> we did it this way. That hopefully helps others who are starting up a project with these technologies.</p>
<p>And of course, some of the choices we made may be flawed. That&#8217;s the reason you can write comments below :&#41; </p>
<p>I created an example project with our setup, see the bottom of this post ([1]). Remember that nowadays you can download a development version of Websphere 7 at no charge at IBM.com. But you can also run this project in jetty ofcourse.</p>
<h2>Configuring JPA</h2>
<h3>Setting up the PersistenceContext</h3>
<p>We decided to use Spring to bootstrap the JPA context. This is not the pure JEE way, I&#8217;ll get back to that in a later section. Spring&#8217;s <a href="http://static.springsource.org/spring/docs/2.5.x/api/org/springframework/orm/jpa/LocalContainerEntityManagerFactoryBean.html">LocalContainerEntityManagerFactoryBean</a> does pretty much what the JEE container should do: bootstrap the JPA persistence context, but with the usual extra Spring flexibility.</p>
<h5>persistence-spring.xml</h5>
<pre class="brush:[xml]">
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"
	version="1.0">
	<!-- Kept as light as possible in order to work with Spring in both J2SE and JEE. -->
<persistence-unit name="example-db">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
		<jta-data-source>java:comp/env/jdbc/testDb</jta-data-source>
	</persistence-unit>
</persistence>
</pre>
<h5>Spring application context</h5>
<pre class="brush:[xml]">&lt;util:properties id="jpaProviderProperties" location="classpath:jpaVendor.properties" /&gt;
&lt;bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"&gt;
&lt;!--
Non-standard filename so Websphere doesn't try to create the EM (and
throw errors due to Hibernate not being on the AS classpath)
--&gt;
&lt;property name="persistenceXmlLocation" value="classpath:META-INF/persistence-spring.xml" /&gt;
&lt;property name="jpaProperties" ref="jpaProviderProperties" /&gt;

&lt;/bean&gt;
</pre>
<p>The location of the persistence-spring.xml is important as it is used to find the Entities you want to persist (more info, see <a href="http://javahowto.blogspot.com/2007/06/where-to-put-persistencexml-in-web-app.html">here</a>). Ignore the jpaVendor.properties for now, I&#8217;ll get to that in the section on integration tests.</p>
<h3>Transaction management</h3>
<h4>Choosing a transaction manager</h4>
<p>In the end, we chose the most future-proof option: a JTA Transaction manager (TM). But we started out with these options:</p>
<ol>
<li>A (in JPA-speak) RESOURCE_LOCAL transaction manager. Spring provides the <a href="http://static.springsource.org/spring/docs/2.5.x/api/org/springframework/orm/jpa/JpaTransactionManager.html">JpaTransactionManager</a>. Cannot handle transactions for more than one XA resource (db, web service call, etc).</li>
<li>A container-provided JTA transaction manager. Websphere provides the <a href="http://publib.boulder.ibm.com/infocenter/wasinfo/v6r0/index.jsp?topic=/com.ibm.websphere.javadoc.doc/public_html/spi/com/ibm/wsspi/uow/UOWManager.html">UOWManager</a> and Spring providers a wrapper around it, offering full JTA support &#8211; transaction suspending, distributed transactions, the works. It can be created through the container-independent &lt;tx:jta-transaction-manager /&gt; in the spring context.</li>
<li>What is all this transaction manager dogma? Do we need it? What&#8217;s wrong with using plain old autocommit?</li>
</ol>
<p>First: do we need a TM at all? Recent experiences at a different project showed that without a TM the use of connection pools is less efficient resulting in sizeable performance penalties, although it&#8217;s not completely clear why. So configuring a transaction manager seems the sensible thing to do. Since JTA is the default choice when running JPA in a JEE container and we had no good reason to reject this option, we went ahead with the default approach. Also, I have the feeling we might have to support <a href="https://www.ibm.com/developerworks/webservices/library/ws-transjta/">WS-Transaction</a> somewhere in the future (yes, YAGNI ;&#41;).</p>
<h4>Transaction boundaries</h4>
<p>Next: how to configure the transaction boundaries. That&#8217;s pretty standard Spring-tx stuff (since we&#8217;re not using EJB3). We use Spring&#8217;s @Transactional annotations on the service layer (the transaction boundary in our application) and the rest is taken care of by Spring&#8217;s &lt;tx:annotation-driven /&gt;. Works like a charm.</p>
<h4>Hibernate configuration</h4>
<p>Hibernate did give some problems with this setup. Since Spring is managing transactions, the only thing Hibernate should do is join the transaction. In order to do this Hibernate needs to look up the transaction manager. Sadly, neither the IBM UOWManager nor the Spring wrapper implements the TransactionManager interface. In the end, this configuration in jpaVendor.properties did the trick:</p>
<blockquote><p>
hibernate.transaction.manager_lookup_class=org.hibernate.transaction.WebSphereExtendedJTATransactionLookup</p></blockquote>
<p>Bottom line: Hibernate is synchronizing to the transaction using a pre-WAS6.1 mechanism, and Spring is using the >=WAS6.1 way. Also, the Hibernate implementation has it&#8217;s problems: setRollbackOnly may be called in application code according to the spec, but this causes a nasty stacktrace in the log. But: it <em>does</em> work correctly. The whole story is explained in detail in <a href="https://forum.hibernate.org/viewtopic.php?f=1&amp;t=992310">this thread</a>.</p>
<p>On a sidenote: something confused me for a while: Hibernate3 configures itself based on the persistence.xml configuration. I noticed that it switched its transaction factory implementation automatically to &#8216;JoinableCMTTransactionFactory&#8217;. CMT is Container managed persistence, and we don&#8217;t use EJB2, since this seemed incorrect. After some time I read the javadoc <a href="http://docs.jboss.org/hibernate/stable/annotations/api/org/hibernate/transaction/CMTTransaction.html">here</a>, and it turns out that this is in fact correct behaviour:</p>
<blockquote><p>The term &#8216;CMT&#8217; is potentially misleading here; the pertinent point simply being that the transactions are being managed by something other than the Hibernate transaction mechanism.</p></blockquote>
<h4>Opening the entity manager on each request</h4>
<p>We also added a filter (<a href="http://static.springsource.org/spring/docs/3.0.0.RC1/javadoc-api/org/springframework/orm/jpa/support/OpenEntityManagerInViewFilter.html">OpenEntityManagerInViewFilter</a>) in the web.xml that sets up a EntityManager that the request starts en destroys it when the request ends (comparable with the OpenSessionInViewFilter for Hibernate).</p>
<h3>Running integration tests / Jetty</h3>
<p>Our data layer is isn&#8217;t unittested, it&#8217;s integration tested (as explained by yet another Vincent <a href="http://blog.xebia.com/2009/07/11/jpa-implementation-patterns-testing/">here</a>). As a rule of thumb, we always try to keep the configuration as identical to the deployment configuration as possible. In this case, the JPA context is set up using the exact same application context file and persistence.xml. The only thing that&#8217;s different are the jpaVendor.properties (in tests, I want Hibernate to use the H2 dialect and to automatically create the DB schema). They are read from the classpath (see sping XML snipplet at the beginning of this post): so you can have separate jpaVendor.properties for your test (src/test/resources) and production (src/main/resources) environment [2].</p>
<p>The resources normally provided by the JEE container (through JNDI) need to be mocked in test mode. This is a nice way to accomplish that:</p>
<pre class="brush:[java]">
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "classpath:spring-config-domain.xml" })
@TransactionConfiguration(defaultRollback = true)
public class UserDaoTest {
[...]
	@BeforeClass
	public static void beforeClass() throws Exception {

		// Suppress the 'close', since we use a single connection in unittest
		// anyways. The connection is terminated upon destruction in afterClass
		singleConnectionDataSource = new SingleConnectionDataSource(
				"jdbc:h2:mem:", true);
		singleConnectionDataSource.setDriverClassName("org.h2.Driver");
		final TransactionAwareDataSourceProxy transactionAwareDataSourceProxy = new TransactionAwareDataSourceProxy(
				singleConnectionDataSource);

		contextBuilder = new SimpleNamingContextBuilder();
		contextBuilder.bind("java:comp/TransactionManager",
				new JotmFactoryBean().getObject());
		contextBuilder.bind("java:comp/env/jdbc/testDb",
				transactionAwareDataSourceProxy);
		contextBuilder.activate();
	}

	@AfterClass
	public static void afterClass() throws Exception {
		contextBuilder.deactivate();
		singleConnectionDataSource.destroy();
	}
[...]
}
</pre>
<p>So, a datasource is registered in JNDI that keeps one connection open at all times (which is pretty handy when using a single threaded H2 DB) and a JOTM (jottum!) TM is used instead of the Websphere TM. The nice thing is the Spring configuration is identical, the &lt;tx:jta-transaction-manager /&gt; finds the JOTM TM now instead. Hibernate does need some manual configuration:</p>
<blockquote><p>hibernate.transaction.manager_lookup_class=org.hibernate.transaction.JOTMTransactionManagerLookup</p></blockquote>
<p>Another bonus: if you want to run your app in a lite JEE container like Jetty for quick deployment, you can use pretty much the same config for that!</p>
<h2>Discussion &#8211; what about JPA by the JEE book?</h2>
<p>According to the EJB3 spec, the container should be in control of the PersistenceContext, roughly as follows:</p>
<ul>
<li>Container detects META-INF/persistence.xml on webapp startup.</li>
<li>Container boots the JPA context based on the provided configuration.</li>
<li>Container sets the PersistenceContext on objects requiring it.</li>
<li>Container exposes the PersistenceContext via JNDI (as defined in the web.xml).</li>
</ul>
<p>Now try this on Websphere 7 (and 6.1 with the EJB3 feature pack, for that matter). As expected (remember: don&#8217;t feed the trolls), Websphere fails if you want to use your own persistence provider (in our case: Hibernate3). According to <a title="IBM" href="http://publib.boulder.ibm.com/infocenter/wasinfo/v7r0/index.jsp?topic=/com.ibm.websphere.express.doc/info/exp/ae/tejb_jpa3rdparty.html" target="_blank">IBM</a> this should be possible by setting the classloader to PARENT_LAST, but alas, that didn&#8217;t seem to work as documented. Messing with heavy weight containers like Websphere is tiresome: you have stop/start redeploy until you&#8217;ve gone cross-eyed. So, the pure JEE configuration for JPA in Websphere wasn&#8217;t convenient for us (which doesn&#8217;t say it&#8217;s impossible) and I personally don&#8217;t see that as a problem &#8211; because it&#8217;s just easier to do it the Spring way &#8211; which can be easily tested in an integration test, instead of deploy-time. </p>
<h2>Final words</h2>
<p>So, is this the best solution? THE way of configuring JPA/JTA/Hibernate/WAS? Of course not. The is no right answer here I think, it all depends on the environment you&#8217;re in. But by explaining why this seems to be a nice fit for our situation, I hope to help those we need to use these technologies but can&#8217;t seem to see the forest for the trees. </p>
<p>Thanks for reading!</p>
<h2>Links</h2>
<p>[1] <a href="http://lussenburg.net/svn/dev/sandbox/jpa-spring-hibernate-example/trunk/">example jpa-spring-hibernate-was project</a><br />
[2] You could also accomplish this by setting a hibernate.properties on your classpath as Hibernate picks this up automatically, but this a more explicit way (but who cares about explicitness anymore in these times of @Autowired magic? :-&#41;).<br />
Keywords: Websphere 6.1 7, JPA, EJB3 , JTA, Transaction management, Spring, Hibernate, Hibernate3</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.smart-java.nl/blog/index.php/2010/05/05/jpa-hibernate3-jta-was7/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Using Unified Expression Language in Maven-Jetty-Plugin</title>
		<link>http://blog.smart-java.nl/blog/index.php/2010/02/27/using-unified-expression-language-in-maven-jetty-plugin/</link>
		<comments>http://blog.smart-java.nl/blog/index.php/2010/02/27/using-unified-expression-language-in-maven-jetty-plugin/#comments</comments>
		<pubDate>Sat, 27 Feb 2010 15:51:57 +0000</pubDate>
		<dc:creator>Jan-Kees van Andel</dc:creator>
				<category><![CDATA[Algemeen]]></category>
		<category><![CDATA[JavaServer Faces]]></category>
		<category><![CDATA[Maven]]></category>
		<category><![CDATA[bean validation]]></category>
		<category><![CDATA[jetty]]></category>
		<category><![CDATA[JSF 2.0]]></category>
		<category><![CDATA[maven]]></category>
		<category><![CDATA[maven-jetty-run]]></category>
		<category><![CDATA[UEL]]></category>
		<category><![CDATA[unified expression language]]></category>

		<guid isPermaLink="false">http://blog.smart-java.nl/blog/?p=927</guid>
		<description><![CDATA[I like the maven-jetty-plugin. If I download an Open Source project, I usually first look for this baby, because it allows me to quickly run the code in a tested environment. This saves me from a lot of configuration, which would otherwise cause me to lose interest. This often doesn&#8217;t take long&#8230;  
Also, you [...]]]></description>
			<content:encoded><![CDATA[<p>I like the maven-jetty-plugin. If I download an Open Source project, I usually first look for this baby, because it allows me to quickly run the code in a tested environment. This saves me from a lot of configuration, which would otherwise cause me to lose interest. This often doesn&#8217;t take long&#8230; <img src='http://blog.smart-java.nl/blog/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<p>Also, you can completely configure the server in your POM, centralizing configuration and making it thus easy to store server settings in version control. Also, the mvn-jetty-plugin benefits from your existing Maven project configuration, like <code>dependencyManagement</code>.</p>
<p>Some of my buddies at Apache even use the maven-jetty-plugin on a daily basis for their real work. I never got this far, mostly because I&#8217;m more familiar with Tomcat, but also because I didn&#8217;t really see it as a mature development tool. However, today I decided to give it a chance.</p>
<p><strong>The first attempt</strong><br />
So, I created a simple webapp in my favorite IDE: <a href="http://www.jetbrains.com/idea/">IntelliJ IDEA</a> and added a Maven2 POM to enable Maven2 support. All well so far.</p>
<p>This was the initial version of my POM:</p>
<pre><script type="syntaxhighlighter" class="brush: xml">
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">

    <modelVersion>4.0.0</modelVersion>

    <groupId>zzz</groupId>
    <artifactId>zzz</artifactId>
<packaging>war</packaging>
    <version>0.1-SNAPSHOT</version>

    <dependencies>
        <dependency>
            <groupId>org.apache.myfaces.core</groupId>
            <artifactId>myfaces-api</artifactId>
            <version>2.0.0-SNAPSHOT</version>
        </dependency>
        <dependency>
            <groupId>org.apache.myfaces.core</groupId>
            <artifactId>myfaces-impl</artifactId>
            <version>2.0.0-SNAPSHOT</version>
        </dependency>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>servlet-api</artifactId>
            <version>2.5</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>javax.servlet.jsp</groupId>
            <artifactId>jsp-api</artifactId>
            <version>2.1</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>javax.validation</groupId>
            <artifactId>validation-api</artifactId>
            <version>1.0.0.GA</version>
        </dependency>
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-validator</artifactId>
            <version>4.0.2.GA</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
            <version>1.5.10</version>
        </dependency>
    </dependencies>

    <repositories>
        <repository>
            <id>jboss</id>
            <url>http://repository.jboss.com/maven2</url>
            <releases>
                <enabled>true</enabled>
            </releases>
            <snapshots>
                <enabled>false</enabled>
            </snapshots>
        </repository>
    </repositories>

    <build>
        <finalName>ueltest</finalName>
<plugins>
<plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>1.6</source>
                    <target>1.6</target>
                </configuration>
            </plugin>
<plugin>
                <groupId>org.mortbay.jetty</groupId>
                <artifactId>maven-jetty-plugin</artifactId>
                <version>6.1.14</version>
                <configuration>
                    <scanIntervalSeconds>1</scanIntervalSeconds>
                    <stopKey>foo</stopKey>
                    <stopPort>9999</stopPort>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>
</script></pre>
<p>All was fine, my test app was running, but I needed to enable <a href="http://www.mojavelinux.com/blog/archives/2009/08/why_you_didnt_know_the_unified_el_is_being_updated/">Unified EL</a> to test <a href="http://myfaces.apache.org/">MyFaces</a> <a href="http://java.sun.com/javaee/6/docs/api/javax/faces/validator/BeanValidator.html">BeanValidator</a>.</p>
<p><strong>Adding UEL libraries</strong><br />
So, I added a dependency to the UEL API and Impl in my POM, but there was an issue. Every web container already provides the old Expression Language in the jsp-api.jar. So I&#8217;m not allowed to package my own EL libraries.</p>
<p>However, I&#8217;m quite stubborn, so I tried anyway:</p>
<pre><script type="syntaxhighlighter" class="brush: xml">
...
<dependencies>
    ...
    <dependency>
        <groupId>javax.el</groupId>
        <artifactId>el-api</artifactId>
        <version>2.2.1-b01</version>
        <scope>compile</scope>
    </dependency>
    <dependency>
        <groupId>org.glassfish.web</groupId>
        <artifactId>el-impl</artifactId>
        <version>2.1.2-b05</version>
        <scope>runtime</scope>
    </dependency>
    ...
</dependencies>
...
</script></pre>
<p>So, let&#8217;s give it a try:
<pre>mvn jetty:run-exploded</pre>
<p> (MyFaces 2.0 requires exploded deployment in Jetty).</p>
<p>Result? BOOOM!</p>
<pre><script type="syntaxhighlighter" class="brush: plain">
java.lang.LinkageError: loader constraint violation: loader (instance of org/mortbay/jetty/webapp/We
bAppClassLoader) previously initiated loading for a different type with name "javax/el/ExpressionFac
tory"
</script></pre>
<p><strong>The fix, replacing libraries</strong><br />
The error is completely appropriate. You&#8217;re just not allowed to package your own version of the servlet libraries. That&#8217;s the job of the servlet container. Failing to do so will result in the error shown above.</p>
<p>So we need to fix this issue by somehow replacing the Jetty libraries or at least changing the way Jetty loads its jsp-api.jar. This is no trivial task however, since jetty is initialized by Maven and doesn&#8217;t have a fixed directory structure on disk.</p>
<p>So we need to have some way in Maven to configure the Jetty libraries.</p>
<p>First, <strong><em>Jetty doesn&#8217;t have an endorsed mechanism</em></strong>, so that&#8217;s a no-go.</p>
<p>But the fix is actually quite easy, just pass some dependencies into the jetty plugin in the POM.</p>
<p>The final POM looks like this:</p>
<pre><script type="syntaxhighlighter" class="brush: xml">
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">

    <modelVersion>4.0.0</modelVersion>

    <groupId>zzz</groupId>
    <artifactId>zzz</artifactId>
<packaging>war</packaging>
    <version>0.1-SNAPSHOT</version>

    <dependencies>
        <dependency>
            <groupId>org.apache.myfaces.core</groupId>
            <artifactId>myfaces-api</artifactId>
            <version>2.0.0-SNAPSHOT</version>
        </dependency>
        <dependency>
            <groupId>org.apache.myfaces.core</groupId>
            <artifactId>myfaces-impl</artifactId>
            <version>2.0.0-SNAPSHOT</version>
        </dependency>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>servlet-api</artifactId>
            <version>2.5</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>javax.servlet.jsp</groupId>
            <artifactId>jsp-api</artifactId>
            <version>2.1</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>javax.validation</groupId>
            <artifactId>validation-api</artifactId>
            <version>1.0.0.GA</version>
        </dependency>
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-validator</artifactId>
            <version>4.0.2.GA</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
            <version>1.5.10</version>
        </dependency>
        <dependency>
            <groupId>javax.el</groupId>
            <artifactId>el-api</artifactId>
            <version>2.2.1-b01</version>
            <scope>provided</scope>
        </dependency>
    </dependencies>

    <repositories>
        <repository>
            <id>jboss</id>
            <url>http://repository.jboss.com/maven2</url>
            <releases>
                <enabled>true</enabled>
            </releases>
            <snapshots>
                <enabled>false</enabled>
            </snapshots>
        </repository>
        <repository>
            <id>glassfish</id>
            <url>http://download.java.net/maven/2</url>
            <releases>
                <enabled>true</enabled>
            </releases>
        </repository>
    </repositories>
<pluginRepositories>
<pluginRepository>
            <id>jboss-plugins</id>
            <url>http://repository.jboss.com/maven2</url>
        </pluginRepository>
    </pluginRepositories>

    <build>
        <finalName>test</finalName>
<plugins>
<plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>1.6</source>
                    <target>1.6</target>
                </configuration>
            </plugin>
<plugin>
                <groupId>org.mortbay.jetty</groupId>
                <artifactId>maven-jetty-plugin</artifactId>
                <version>6.1.14</version>
                <configuration>
                    <scanIntervalSeconds>1</scanIntervalSeconds>
                    <stopKey>foo</stopKey>
                    <stopPort>9999</stopPort>
                </configuration>
                <dependencies>
                    <dependency>
                        <groupId>javax.servlet.jsp</groupId>
                        <artifactId>jsp-api</artifactId>
                        <version>2.2</version>
                        <scope>provided</scope>
                    </dependency>
                    <dependency>
                        <groupId>javax.el</groupId>
                        <artifactId>el-api</artifactId>
                        <version>2.2.1-b01</version>
                        <scope>provided</scope>
                    </dependency>
                    <dependency>
                        <groupId>org.glassfish.web</groupId>
                        <artifactId>el-impl</artifactId>
                        <version>2.2.1-b01</version>
                        <scope>provided</scope>
                    </dependency>
                    <dependency>
                        <groupId>org.mortbay.jetty</groupId>
                        <artifactId>jsp-2.1</artifactId>
                        <version>6.1.14</version>
                        <scope>provided</scope>
                        <exclusions>
                            <exclusion>
                                <groupId>org.mortbay.jetty</groupId>
                                <artifactId>jsp-api-2.1</artifactId>
                            </exclusion>
                            <exclusion>
                                <groupId>org.mortbay.jetty</groupId>
                                <artifactId>start</artifactId>
                            </exclusion>
                            <exclusion>
                                <groupId>org.mortbay.jetty</groupId>
                                <artifactId>jetty-annotations</artifactId>
                            </exclusion>
                        </exclusions>
                    </dependency>
                </dependencies>
</plugin>
        </plugins>
    </build>
</project>
</script></pre>
<p>As you can see, Maven takes care of the heavy lifting. You only need to specify your dependencies and they will override any dependencies with the same groupId, artifactId and type.</p>
<p>So, now I don&#8217;t have any reason not to use mvn-jetty-run to test my code!</p>
<p>Happy coding!</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.smart-java.nl/blog/index.php/2010/02/27/using-unified-expression-language-in-maven-jetty-plugin/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>JPA 2.0 &#8230; finally final</title>
		<link>http://blog.smart-java.nl/blog/index.php/2009/12/11/jpa-2-0-finally-final/</link>
		<comments>http://blog.smart-java.nl/blog/index.php/2009/12/11/jpa-2-0-finally-final/#comments</comments>
		<pubDate>Fri, 11 Dec 2009 10:29:49 +0000</pubDate>
		<dc:creator>Peter Schuler</dc:creator>
				<category><![CDATA[Java API]]></category>
		<category><![CDATA[Object Relational Mapping]]></category>
		<category><![CDATA[Tools/Frameworks]]></category>
		<category><![CDATA[EclipseLink]]></category>
		<category><![CDATA[JPA 2.0]]></category>
		<category><![CDATA[ORM]]></category>
		<category><![CDATA[release]]></category>

		<guid isPermaLink="false">http://blog.smart-java.nl/blog/?p=556</guid>
		<description><![CDATA[Thursday 10 December the people from EclipseLink release version 2.0 of their Object Relation Mapping framework. Besides other improvements this release includes the reference implementation of JPA 2.0.  This means that the JPA 2.0 and JSR-317 are now final!
The second release of the Jave Persistence API adds a lot of new features to the JPA [...]]]></description>
			<content:encoded><![CDATA[<p>Thursday 10 December the people from EclipseLink release version 2.0 of their <em>Object Relation Mapping</em> framework. Besides other improvements this release includes the reference implementation of JPA 2.0.  This means that the JPA 2.0 and JSR-317 are now final!</p>
<p>The second release of the <em>Jave Persistence API</em> adds a lot of new features to the JPA framework. The team responsible for this release now claims to serve 95% of the persistence needs of Java programmers. You can get the final version of <a href="http://jcp.org/en/jsr/detail?id=317" target="_blank">JSR-317 </a>or download the reference implementation on the <a href="http://www.eclipse.org/eclipselink/downloads/index.php#2.0.0" target="_blank">eclipselink website</a>. Two older blogs by Mike Keith introduces all the new features <a href="http://java.dzone.com/articles/looking-forward-jpa-20">here </a>and <a href="http://java.dzone.com/articles/looking-forward-to-jpa-20-part">here</a>.</p>
<p>Version 2.0 now has (among others) support for:</p>
<ul>
<li><a href="http://blog.smart-java.nl/blog/index.php/2010/01/14/jpa-optimisitic-locking-versus-pessimitic-locking/">Increased locking possibilities;</a></li>
<li>Support for Criteria Queries and a MetaModel;</li>
<li>(A little) support for second level caching;</li>
<li>Basic Element and embeddable collections;</li>
<li>Orphan removals for sets;</li>
<li>Derived Identifiers (using @ManyToOne as past of your primary key);</li>
<li>Ordered list.</li>
</ul>
<p>With these new features the Java Persistence API becomes even more useful. In the next  few weeks I will blog some more about the new features and go deeper into some of the new features and how to use them to your advantange.</p>
<p>So stay tuned.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.smart-java.nl/blog/index.php/2009/12/11/jpa-2-0-finally-final/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Temporale data – deel 4: bitemporale collections</title>
		<link>http://blog.smart-java.nl/blog/index.php/2009/12/07/temporale-data-%e2%80%93-deel-4-bitemporale-collections/</link>
		<comments>http://blog.smart-java.nl/blog/index.php/2009/12/07/temporale-data-%e2%80%93-deel-4-bitemporale-collections/#comments</comments>
		<pubDate>Mon, 07 Dec 2009 11:36:20 +0000</pubDate>
		<dc:creator>gnoij</dc:creator>
				<category><![CDATA[Algemeen]]></category>
		<category><![CDATA[Java language]]></category>
		<category><![CDATA[Tools/Frameworks]]></category>
		<category><![CDATA[patterns]]></category>
		<category><![CDATA[bitemporal pattern]]></category>
		<category><![CDATA[temporale data]]></category>

		<guid isPermaLink="false">http://blog.smart-java.nl/blog/?p=551</guid>
		<description><![CDATA[Het is alweer enige tijd geleden dat ik heb geschreven over temporale patterns. In dit deel wil ik het bitemporale pattern uitbreiden met bitemporale collections. Werd met de bitemporale property nog een enkele property historisch gemaakt, in dit deel maken we een lijst historisch. Dat wil zeggen dat er meerdere elementen van een historische lijst [...]]]></description>
			<content:encoded><![CDATA[<p>Het is alweer enige tijd geleden dat ik heb geschreven over <a href="http://blog.smart-java.nl/blog/index.php/2008/11/19/temporale-data-%e2%80%93-deel-1-de-concepten/">temporale patterns</a>. In dit deel wil ik het <a href="http://blog.smart-java.nl/blog/index.php/2008/12/22/temporale-data-%e2%80%93-deel-3-het-bitemporale-pattern/">bitemporale pattern</a> uitbreiden met bitemporale collections. Werd met de bitemporale property nog een enkele property historisch gemaakt, in dit deel maken we een lijst historisch. Dat wil zeggen dat er meerdere elementen van een historische lijst tegelijkertijd geldig kunnen zijn.</p>
<p>De klasse <code>BiTemporalObject</code> uit het derde deel blijft hetzelfde. En naast de <code>BiTemporalProperty</code> voor enkelvoudige historische relaties krijgen we nu ook een klasse <code>BiTemporalCollection</code> voor meervoudige historische relaties.</p>
<p><strong>BiTemporalCollection</strong></p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> BiTemporalCollection <span style="color: #009900;">&#123;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">protected</span> <span style="color: #003399;">List</span> alleHistorischeVersies <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">ArrayList</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> BiTemporalCollection<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">super</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #003399;">List</span> getActueleVersies<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">return</span> getVersieOp<span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">Date</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>, <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">Date</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #003399;">List</span> getVersieOp<span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">final</span> <span style="color: #003399;">Date</span> registratieTijdstip, <span style="color: #000000; font-weight: bold;">final</span> <span style="color: #003399;">Date</span> peilDatum<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #009900;">&#40;</span><span style="color: #003399;">List</span><span style="color: #009900;">&#41;</span> CollectionUtils.<span style="color: #006633;">select</span><span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">alleHistorischeVersies</span>, <span style="color: #000000; font-weight: bold;">new</span> Predicate<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">boolean</span> evaluate<span style="color: #009900;">&#40;</span><span style="color: #003399;">Object</span> object<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
                <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span>BiTemporalObject<span style="color: #009900;">&#41;</span> object<span style="color: #009900;">&#41;</span>.<span style="color: #006633;">isGeldigOp</span><span style="color: #009900;">&#40;</span>registratieTijdstip, peilDatum<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
            <span style="color: #009900;">&#125;</span>
        <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> voegActueleVersieToe<span style="color: #009900;">&#40;</span>BiTemporalObject actueleVersie<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>actueleVersie <span style="color: #339933;">==</span> <span style="color: #000066; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #000000; font-weight: bold;">throw</span> <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">IllegalArgumentException</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;actueleVersie is null&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
        <span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">alleHistorischeVersies</span>.<span style="color: #006633;">add</span><span style="color: #009900;">&#40;</span>actueleVersie<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> wijzigActueleVersie<span style="color: #009900;">&#40;</span>BiTemporalObject nieuweVersie, BiTemporalObject oudeVersie<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>nieuweVersie <span style="color: #339933;">==</span> <span style="color: #000066; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #000000; font-weight: bold;">throw</span> <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">IllegalArgumentException</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;nieuweVersie is null&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
        <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>oudeVersie <span style="color: #339933;">==</span> <span style="color: #000066; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #000000; font-weight: bold;">throw</span> <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">IllegalArgumentException</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;oudeVersie is null&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
        beeindigVorigeVersie<span style="color: #009900;">&#40;</span>nieuweVersie, oudeVersie<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">alleHistorischeVersies</span>.<span style="color: #006633;">add</span><span style="color: #009900;">&#40;</span>nieuweVersie<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000066; font-weight: bold;">void</span> beeindigVorigeVersie<span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">final</span> BiTemporalObject nieuweVersie, <span style="color: #000000; font-weight: bold;">final</span> BiTemporalObject oudeVersie<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
&nbsp;
        BiTemporalObject afTeVoerenVersie <span style="color: #339933;">=</span> zoekActueleVersie<span style="color: #009900;">&#40;</span>oudeVersie, nieuweVersie.<span style="color: #006633;">getIngangsdatum</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>, nieuweVersie.<span style="color: #006633;">getOpvoerTijdstip</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> 
&nbsp;
        <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>afTeVoerenVersie <span style="color: #339933;">==</span> <span style="color: #000066; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #000000; font-weight: bold;">throw</span> <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">IllegalStateException</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;Geen oude actuele versie gevonden!&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
&nbsp;
        beeindigVersie<span style="color: #009900;">&#40;</span>afTeVoerenVersie, nieuweVersie.<span style="color: #006633;">getIngangsdatum</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>, nieuweVersie.<span style="color: #006633;">getOpvoerTijdstip</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> beeindig<span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">final</span> BiTemporalObject actueleVersie, <span style="color: #000000; font-weight: bold;">final</span> <span style="color: #003399;">Date</span> einddatum<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        BiTemporalObject afTeVoerenVersie <span style="color: #339933;">=</span> zoekActueleVersie<span style="color: #009900;">&#40;</span>actueleVersie, einddatum, <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">Date</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>afTeVoerenVersie <span style="color: #339933;">==</span> <span style="color: #000066; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #000000; font-weight: bold;">throw</span> <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">IllegalStateException</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;Geen oude actuele versie gevonden!&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
        beeindigVersie<span style="color: #009900;">&#40;</span>afTeVoerenVersie, einddatum, <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">Date</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> beeindig<span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">final</span> <span style="color: #003399;">Date</span> einddatum<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #003399;">List</span> afTeVoerenVersies <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span><span style="color: #003399;">List</span><span style="color: #009900;">&#41;</span> CollectionUtils.<span style="color: #006633;">select</span><span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">alleHistorischeVersies</span>, <span style="color: #000000; font-weight: bold;">new</span> Predicate<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">boolean</span> evaluate<span style="color: #009900;">&#40;</span><span style="color: #003399;">Object</span> object<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
                BiTemporalObject versie <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span>BiTemporalObject<span style="color: #009900;">&#41;</span> object<span style="color: #339933;">;</span>
                <span style="color: #000000; font-weight: bold;">return</span> versie.<span style="color: #006633;">isGeldigOp</span><span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">Date</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>, einddatum<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
            <span style="color: #009900;">&#125;</span>
        <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        CollectionUtils.<span style="color: #006633;">forAllDo</span><span style="color: #009900;">&#40;</span>afTeVoerenVersies, <span style="color: #000000; font-weight: bold;">new</span> Closure<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> execute<span style="color: #009900;">&#40;</span><span style="color: #003399;">Object</span> input<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
                beeindigVersie<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span>BiTemporalObject<span style="color: #009900;">&#41;</span> input, einddatum, <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">Date</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
            <span style="color: #009900;">&#125;</span>
        <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000066; font-weight: bold;">void</span> beeindigVersie<span style="color: #009900;">&#40;</span>BiTemporalObject versie, <span style="color: #003399;">Date</span> einddatum, <span style="color: #003399;">Date</span> registratieTijdstip<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        BiTemporalObject kopieVersie <span style="color: #339933;">=</span> versie.<span style="color: #006633;">kopieer</span><span style="color: #009900;">&#40;</span>einddatum, registratieTijdstip<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">alleHistorischeVersies</span>.<span style="color: #006633;">add</span><span style="color: #009900;">&#40;</span>kopieVersie<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">private</span> BiTemporalObject zoekActueleVersie<span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">final</span> BiTemporalObject actueleVersie, <span style="color: #000000; font-weight: bold;">final</span> <span style="color: #003399;">Date</span> peildatum, <span style="color: #000000; font-weight: bold;">final</span> <span style="color: #003399;">Date</span> registratieTijdstip<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #009900;">&#40;</span>BiTemporalObject<span style="color: #009900;">&#41;</span> CollectionUtils.<span style="color: #006633;">find</span><span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">alleHistorischeVersies</span>, <span style="color: #000000; font-weight: bold;">new</span> Predicate<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">boolean</span> evaluate<span style="color: #009900;">&#40;</span><span style="color: #003399;">Object</span> object<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
                BiTemporalObject versie <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span>BiTemporalObject<span style="color: #009900;">&#41;</span> object<span style="color: #339933;">;</span>
                <span style="color: #000000; font-weight: bold;">return</span> versie.<span style="color: #006633;">equals</span><span style="color: #009900;">&#40;</span>actueleVersie<span style="color: #009900;">&#41;</span> <span style="color: #339933;">&amp;&amp;</span> versie.<span style="color: #006633;">isGeldigOp</span><span style="color: #009900;">&#40;</span>registratieTijdstip, peildatum<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
            <span style="color: #009900;">&#125;</span>
        <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span></pre></div></div>

<p>De wijzigingen ten opzichte van de <code>BiTemporalProperty</code> uit het vorige deel zijn dat er nu niet één maar meer versies tegelijkertijd geldig kunnen zijn (<code>getActueleVersies</code>) en dat we versies kunnen toevoegen (<code>voegActueleVersieToe</code>) en kunnen wijzigen (<code>wijzigActueleVersie</code>). Bij deze laatste methode we de te wijzigen versie meegeven, zodat deze beëindigd kan worden en de nieuwe versie toegevoegd wordt. Ook  kunnen we alle versies van de collection beëindigen (<code>beeindig</code>) of een enkele versie (die dan weer aan de methode meegegeven moet worden).</p>
<h3>Een voorbeeld</h3>
<p>In dit voorbeeld wordt het voorbeeld uit deel 3 uitgebreid met een manager (zelf ook een werknemer), die meerdere werknemers onder zich heeft. </p>
<p><strong>Manager</strong></p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> Manager <span style="color: #000000; font-weight: bold;">extends</span> Werknemer <span style="color: #009900;">&#123;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000000; font-weight: bold;">static</span> <span style="color: #000000; font-weight: bold;">final</span> <span style="color: #000066; font-weight: bold;">long</span> serialVersionUID <span style="color: #339933;">=</span> 1L<span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">private</span> BiTemporalCollection werknemers <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> BiTemporalCollection<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> Manager<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">super</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> Manager<span style="color: #009900;">&#40;</span><span style="color: #003399;">String</span> naam<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">super</span><span style="color: #009900;">&#40;</span>naam<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> voegWerknemerToe<span style="color: #009900;">&#40;</span>Werknemer werknemer, <span style="color: #003399;">Date</span> ingangsdatum<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">werknemers</span>.<span style="color: #006633;">voegActueleVersieToe</span><span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">new</span> WerknemerRelatie<span style="color: #009900;">&#40;</span>werknemer, ingangsdatum<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #003399;">List</span> getTeManagenWerknemers<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #003399;">List</span> relaties <span style="color: #339933;">=</span> getWerknemerRelaties<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        CollectionUtils.<span style="color: #006633;">transform</span><span style="color: #009900;">&#40;</span>relaties, <span style="color: #000000; font-weight: bold;">new</span> Transformer<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #003399;">Object</span> transform<span style="color: #009900;">&#40;</span><span style="color: #003399;">Object</span> object<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
                <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span>WerknemerRelatie<span style="color: #009900;">&#41;</span>object<span style="color: #009900;">&#41;</span>.<span style="color: #006633;">getWerknemer</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
            <span style="color: #009900;">&#125;</span>
        <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">;</span>
        <span style="color: #000000; font-weight: bold;">return</span> relaties<span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #003399;">List</span> getTeManagenWerknemers<span style="color: #009900;">&#40;</span><span style="color: #003399;">Date</span> registratieTijdstip, <span style="color: #003399;">Date</span> peildatum<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #003399;">List</span> relaties <span style="color: #339933;">=</span> getWerknemerRelaties<span style="color: #009900;">&#40;</span>registratieTijdstip, peildatum<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        CollectionUtils.<span style="color: #006633;">transform</span><span style="color: #009900;">&#40;</span>relaties, <span style="color: #000000; font-weight: bold;">new</span> Transformer<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #003399;">Object</span> transform<span style="color: #009900;">&#40;</span><span style="color: #003399;">Object</span> object<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
                <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span>WerknemerRelatie<span style="color: #009900;">&#41;</span>object<span style="color: #009900;">&#41;</span>.<span style="color: #006633;">getWerknemer</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
            <span style="color: #009900;">&#125;</span>
        <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">;</span>
        <span style="color: #000000; font-weight: bold;">return</span> relaties<span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #003399;">List</span> getWerknemerRelaties<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">werknemers</span>.<span style="color: #006633;">getActueleVersies</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #003399;">List</span> getWerknemerRelaties<span style="color: #009900;">&#40;</span><span style="color: #003399;">Date</span> registratieTijdstip, <span style="color: #003399;">Date</span> peildatum<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">werknemers</span>.<span style="color: #006633;">getVersieOp</span><span style="color: #009900;">&#40;</span>registratieTijdstip, peildatum<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> wijzigWerknemer<span style="color: #009900;">&#40;</span>Werknemer nieuweWerknemer, Werknemer oudeWerknemer, <span style="color: #003399;">Date</span> wijzigingsdatum<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        WerknemerRelatie nieuweRelatie <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> WerknemerRelatie<span style="color: #009900;">&#40;</span>nieuweWerknemer, wijzigingsdatum<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        WerknemerRelatie oudeRelatie <span style="color: #339933;">=</span> bepaalWerknemerRelatie<span style="color: #009900;">&#40;</span>oudeWerknemer<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">werknemers</span>.<span style="color: #006633;">wijzigActueleVersie</span><span style="color: #009900;">&#40;</span>nieuweRelatie, oudeRelatie<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">private</span> WerknemerRelatie bepaalWerknemerRelatie<span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">final</span> Werknemer werknemer<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #009900;">&#40;</span>WerknemerRelatie<span style="color: #009900;">&#41;</span>CollectionUtils.<span style="color: #006633;">find</span><span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">werknemers</span>.<span style="color: #006633;">getActueleVersies</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>, <span style="color: #000000; font-weight: bold;">new</span> Predicate<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">boolean</span> evaluate<span style="color: #009900;">&#40;</span><span style="color: #003399;">Object</span> obj<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
                <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span>WerknemerRelatie<span style="color: #009900;">&#41;</span>obj<span style="color: #009900;">&#41;</span>.<span style="color: #006633;">getWerknemer</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">equals</span><span style="color: #009900;">&#40;</span>werknemer<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
            <span style="color: #009900;">&#125;</span>
        <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> stopManagenVanWerknemer<span style="color: #009900;">&#40;</span>Werknemer werknemer, <span style="color: #003399;">Date</span> einddatum<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        WerknemerRelatie relatie <span style="color: #339933;">=</span> bepaalWerknemerRelatie<span style="color: #009900;">&#40;</span>werknemer<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">werknemers</span>.<span style="color: #006633;">beeindig</span><span style="color: #009900;">&#40;</span>relatie, einddatum<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> stopManagen<span style="color: #009900;">&#40;</span><span style="color: #003399;">Date</span> einddatum<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">werknemers</span>.<span style="color: #006633;">beeindig</span><span style="color: #009900;">&#40;</span>einddatum<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Deze klasse representeert de manager. Als een manager een werknemer gaat managen, wordt de werknemer toegevoegd aan de lijst van te managen werknemers (<code>voegWerknemerToe</code>). Als een werknemer wordt vervangen door een andere werknemer wordt de methode <code>wijzigWerknemer</code> aangeroepen, waardoor de relatie met de oude werknemer wordt beëindigd en de nieuwe werknemer wordt begonnen. Als een werknemer uit dienst gaat of naar een andere afdeling, stopt de manager met het managen van deze werknemer (<code>stopManagenVanWerknemer</code>), waardoor de historische relatie van de manager met de werknemer wordt beëindigd. Als de manager stopt met managen (<code>stopManagen</code>), wordt de relatie met alle gemanagede werknemers beëindigd.</p>
<p>De historische relatie van de manager met de werknemer wordt gerepresenteerd door de klasse <code>WerknemerRelatie</code>.</p>
<p><strong>WerknemerRelatie</strong></p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> WerknemerRelatie <span style="color: #000000; font-weight: bold;">extends</span> BiTemporalObject <span style="color: #009900;">&#123;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000000; font-weight: bold;">static</span> <span style="color: #000000; font-weight: bold;">final</span> <span style="color: #000066; font-weight: bold;">long</span> serialVersionUID <span style="color: #339933;">=</span> 1L<span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">private</span> Werknemer werknemer<span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">protected</span> WerknemerRelatie<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">super</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">protected</span> WerknemerRelatie<span style="color: #009900;">&#40;</span>Werknemer werknemer, <span style="color: #003399;">Date</span> ingangsdatum<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">super</span><span style="color: #009900;">&#40;</span>ingangsdatum<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">werknemer</span><span style="color: #339933;">=</span> werknemer<span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> Werknemer getWerknemer<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">werknemer</span> <span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>De test ziet er als volgt uit:</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> testManager<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
&nbsp;
	Manager jan <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Manager<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;Jan&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #666666; font-style: italic;">// simuleer de opvoer tijd 1-1-2003</span>
	<span style="color: #003399;">Date</span> aanvangsdatum <span style="color: #339933;">=</span> DateUtils.<span style="color: #006633;">maakDate</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">2003</span>, <span style="color: #cc66cc;">1</span>, <span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	BiTemporalObject.<span style="color: #006633;">TEST_OPVOER_TIJDSTIP</span> <span style="color: #339933;">=</span> aanvangsdatum<span style="color: #339933;">;</span> 
&nbsp;
	Afdeling inkoop <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Afdeling<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;Inkoop&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	jan.<span style="color: #006633;">setAfdeling</span><span style="color: #009900;">&#40;</span>inkoop, aanvangsdatum<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
	Werknemer kees <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Werknemer<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;Kees&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	kees.<span style="color: #006633;">setAfdeling</span><span style="color: #009900;">&#40;</span>inkoop, aanvangsdatum<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	jan.<span style="color: #006633;">voegWerknemerToe</span><span style="color: #009900;">&#40;</span>kees, aanvangsdatum<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
	Werknemer piet <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Werknemer<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;Piet&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	piet.<span style="color: #006633;">setAfdeling</span><span style="color: #009900;">&#40;</span>inkoop, aanvangsdatum<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	jan.<span style="color: #006633;">voegWerknemerToe</span><span style="color: #009900;">&#40;</span>piet, aanvangsdatum<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
	assertEquals<span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">2</span>, jan.<span style="color: #006633;">getTeManagenWerknemers</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">size</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	assertTrue<span style="color: #009900;">&#40;</span>jan.<span style="color: #006633;">getTeManagenWerknemers</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">contains</span><span style="color: #009900;">&#40;</span>kees<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	assertTrue<span style="color: #009900;">&#40;</span>jan.<span style="color: #006633;">getTeManagenWerknemers</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">contains</span><span style="color: #009900;">&#40;</span>piet<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #003399;">Date</span> wijzigingsdatum <span style="color: #339933;">=</span> DateUtils.<span style="color: #006633;">maakDate</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">2006</span>, <span style="color: #cc66cc;">1</span>, <span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	BiTemporalObject.<span style="color: #006633;">TEST_OPVOER_TIJDSTIP</span> <span style="color: #339933;">=</span> wijzigingsdatum<span style="color: #339933;">;</span> 
&nbsp;
	Werknemer johan <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Werknemer<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;Johan&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	johan.<span style="color: #006633;">setAfdeling</span><span style="color: #009900;">&#40;</span>inkoop, wijzigingsdatum<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #666666; font-style: italic;">// Johan vervangt Piet, die uit dienst gaat</span>
	jan.<span style="color: #006633;">wijzigWerknemer</span><span style="color: #009900;">&#40;</span>johan, piet, wijzigingsdatum<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	piet.<span style="color: #006633;">uitDienst</span><span style="color: #009900;">&#40;</span>wijzigingsdatum<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
	assertEquals<span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">2</span>, jan.<span style="color: #006633;">getTeManagenWerknemers</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">size</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	assertTrue<span style="color: #009900;">&#40;</span>jan.<span style="color: #006633;">getTeManagenWerknemers</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">contains</span><span style="color: #009900;">&#40;</span>johan<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	assertFalse<span style="color: #009900;">&#40;</span>jan.<span style="color: #006633;">getTeManagenWerknemers</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">contains</span><span style="color: #009900;">&#40;</span>piet<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #666666; font-style: italic;">// jan managete gisteren piet nog wel</span>
	<span style="color: #003399;">Date</span> gisteren <span style="color: #339933;">=</span> DateUtils.<span style="color: #006633;">maakDate</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">2005</span>, <span style="color: #cc66cc;">12</span>, <span style="color: #cc66cc;">31</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	assertTrue<span style="color: #009900;">&#40;</span>jan.<span style="color: #006633;">getTeManagenWerknemers</span><span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">Date</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>, gisteren<span style="color: #009900;">&#41;</span>.<span style="color: #006633;">contains</span><span style="color: #009900;">&#40;</span>piet<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #003399;">Date</span> einddatum <span style="color: #339933;">=</span> DateUtils.<span style="color: #006633;">maakDate</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">2009</span>, <span style="color: #cc66cc;">1</span>, <span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	BiTemporalObject.<span style="color: #006633;">TEST_OPVOER_TIJDSTIP</span> <span style="color: #339933;">=</span> wijzigingsdatum<span style="color: #339933;">;</span> 
&nbsp;
	jan.<span style="color: #006633;">stopManagenVanWerknemer</span><span style="color: #009900;">&#40;</span>kees, einddatum<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	kees.<span style="color: #006633;">uitDienst</span><span style="color: #009900;">&#40;</span>einddatum<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
	assertEquals<span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">1</span>, jan.<span style="color: #006633;">getTeManagenWerknemers</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">size</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	assertFalse<span style="color: #009900;">&#40;</span>jan.<span style="color: #006633;">getTeManagenWerknemers</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">contains</span><span style="color: #009900;">&#40;</span>kees<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
	jan.<span style="color: #006633;">stopManagen</span><span style="color: #009900;">&#40;</span>einddatum<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	assertTrue<span style="color: #009900;">&#40;</span>jan.<span style="color: #006633;">getTeManagenWerknemers</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">isEmpty</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>In deze test maken we een manager Jan aan, die werkt op de afdeling Inkoop op 1 januari 2003. Vanaf deze dag begint hij ook met het managen van twee werknemers Kees en Piet. Vanaf 1 januari 2006 vervangt een nieuwe werknemer Johan Piet, die uit dienst gaat. Op 1 januari 2009 stopt Jan met het managen van al zijn werknemers.</p>
<h3>Hibernate mappings</h3>
<p>De hibernate mapping van de klasse <code>WerknemerRelatie<code> is analoog aan de mapping van de <code>AfdelingRelatie</code> uit deel 3. </p>
<p>De mapping van de werknemer is uitgebreid met de subclass Manager, die de werknemers als BiTemporalCollection property mapt. </p>
<p><strong>Werknemer.hbm.xml</strong></p>

<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;hibernate-mapping</span> <span style="color: #000066;">package</span>=<span style="color: #ff0000;">&quot;nl.ordina.bitemporal.example&quot;</span> <span style="color: #000066;">default-access</span>=<span style="color: #ff0000;">&quot;field&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
	<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;class</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;Werknemer&quot;</span> <span style="color: #000066;">table</span>=<span style="color: #ff0000;">&quot;Werknemer&quot;</span> <span style="color: #000066;">discriminator-value</span>=<span style="color: #ff0000;">&quot;Werknemer&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
		<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;id</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;id&quot;</span> <span style="color: #000066;">column</span>=<span style="color: #ff0000;">&quot;id&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
			<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;generator</span> <span style="color: #000066;">class</span>=<span style="color: #ff0000;">&quot;identity&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span><span style="color: #000000; font-weight: bold;">&lt;/generator<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
		<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/id<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
		<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;discriminator</span> <span style="color: #000066;">column</span>=<span style="color: #ff0000;">&quot;type&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
		<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;version</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;versie&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
&nbsp;
		<span style="color: #808080; font-style: italic;">&lt;!-- properties --&gt;</span>
		<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;property</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;naam&quot;</span> <span style="color: #000066;">column</span>=<span style="color: #ff0000;">&quot;naam&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
&nbsp;
		<span style="color: #808080; font-style: italic;">&lt;!-- de verwijzing naar de afdelingrelatie --&gt;</span>
		<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;component</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;afdelingRelatie&quot;</span> </span>
<span style="color: #009900;">			<span style="color: #000066;">class</span>=<span style="color: #ff0000;">&quot;nl.ordina.temporal.bitemporal.BiTemporalProperty&quot;</span></span>
<span style="color: #009900;">			<span style="color: #000066;">lazy</span>=<span style="color: #ff0000;">&quot;false&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
			<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;bag</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;alleHistorischeVersies&quot;</span></span>
<span style="color: #009900;">				<span style="color: #000066;">cascade</span>=<span style="color: #ff0000;">&quot;all, delete-orphan&quot;</span> <span style="color: #000000; font-weight: bold;">&gt;</span></span>
				<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key</span> <span style="color: #000066;">column</span>=<span style="color: #ff0000;">&quot;werknemerId&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
				<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;one-to-many</span></span>
<span style="color: #009900;">					<span style="color: #000066;">class</span>=<span style="color: #ff0000;">&quot;AfdelingRelatie&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
			<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/bag<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
		<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/component<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
&nbsp;
		<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;subclass</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;Manager&quot;</span> <span style="color: #000066;">discriminator-value</span>=<span style="color: #ff0000;">&quot;Manager&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
		<span style="color: #808080; font-style: italic;">&lt;!-- de verwijzing naar de werknemerrelatie --&gt;</span>
			<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;component</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;werknemers&quot;</span> </span>
<span style="color: #009900;">				<span style="color: #000066;">class</span>=<span style="color: #ff0000;">&quot;nl.ordina.temporal.bitemporal.BiTemporalCollection&quot;</span></span>
<span style="color: #009900;">				<span style="color: #000066;">lazy</span>=<span style="color: #ff0000;">&quot;false&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
				<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;bag</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;alleHistorischeVersies&quot;</span></span>
<span style="color: #009900;">					<span style="color: #000066;">cascade</span>=<span style="color: #ff0000;">&quot;all, delete-orphan&quot;</span> <span style="color: #000000; font-weight: bold;">&gt;</span></span>
					<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key</span> <span style="color: #000066;">column</span>=<span style="color: #ff0000;">&quot;managerId&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
					<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;one-to-many</span></span>
<span style="color: #009900;">						<span style="color: #000066;">class</span>=<span style="color: #ff0000;">&quot;WerknemerRelatie&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
				<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/bag<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
			<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/component<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
		<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/subclass<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
	<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/class<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/hibernate-mapping<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></div></div>

<p><strong>LET OP</strong>: In bovenstaand artikel wordt gesproken over <code>BiTemporalCollection</code>. Dit is niet dezelfde als de <a href="http://martinfowler.com/ap2/temporalProperty.html">BiTemporalCollection van Fowler</a> , wat eigenlijk de <code>BiTemporalProperty</code> uit deel 3 is.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.smart-java.nl/blog/index.php/2009/12/07/temporale-data-%e2%80%93-deel-4-bitemporale-collections/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Getting on the cloud!</title>
		<link>http://blog.smart-java.nl/blog/index.php/2009/06/05/getting-on-the-cloud/</link>
		<comments>http://blog.smart-java.nl/blog/index.php/2009/06/05/getting-on-the-cloud/#comments</comments>
		<pubDate>Fri, 05 Jun 2009 19:35:51 +0000</pubDate>
		<dc:creator>Roy van Rijn</dc:creator>
				<category><![CDATA[Middleware]]></category>
		<category><![CDATA[Spring]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[app engine]]></category>
		<category><![CDATA[cloud computing]]></category>
		<category><![CDATA[google]]></category>
		<category><![CDATA[spring]]></category>
		<category><![CDATA[wicket]]></category>

		<guid isPermaLink="false">http://blog.smart-java.nl/blog/?p=417</guid>
		<description><![CDATA[You&#8217;ve probably heard people talking before about &#8216;cloud computing&#8217;.
But what exacly is this cloud computing you might ask? 
To figure this out I decided to create my own Google App Engine project and find out about cloud computing along the way. 
Wikipedia states that cloud computing is:
&#8220;Cloud computing is a style of computing in which [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://blog.smart-java.nl/blog/wp-content/uploads/2009/06/appengine.gif" alt="Google App Engine" title="appengine_logo" width="142" height="109" class="size-medium wp-image-432" /></p>
<p>You&#8217;ve probably heard people talking before about &#8216;cloud computing&#8217;.<br />
But what exacly is this cloud computing you might ask? </p>
<p>To figure this out I decided to create my own Google App Engine project and find out about cloud computing along the way. </p>
<p>Wikipedia states that cloud computing is:</p>
<p><em>&#8220;<strong>Cloud computing</strong> is a style of computing in which dynamically <strong>scalable</strong> and often <strong>virtualized</strong> resources are provided <strong>as a service</strong> over the Internet. Users need not have knowledge of, expertise in, or control over the technology infrastructure in the &#8220;cloud&#8221; that supports them&#8221;</em></p>
<p>So, cloud computing doesn&#8217;t only have a vague name, the description isn&#8217;t very helpful either. But the key ingredients are &#8220;scalable&#8221; and &#8220;virtualized&#8221; and &#8220;as a service&#8221;. And you don&#8217;t have control over the infrastructure&#8230;</p>
<p>Lets take a look at Google App Engine. It was released in April 2008 as a platform for developing (Python)cloud applications. App Engine hosts these applications virtually on many machines, the programs are distributed and scaled across a vast amount of servers. And now, since the beginning of this year Google App Engine also supports Java!</p>
<p>The concept is simple, you get to build an application, preferably using Google&#8217;s App Engine-eclipse-plugin. And the JRE you build on is a slightly stripped-down version to make it usable on a cloud, like a sandbox.</p>
<p>Because you don&#8217;t know on what kind of servers your application will run on, or on how many servers, Google has decided you can&#8217;t do the following:</p>
<ul>
<li>Start threads</li>
<li>Go to the Filesystem, no I/O</li>
<li>Open sockets directly, but you can open connections through HTTP/HTTPS</li>
<li>Make calls to System (like exit();, gc(); etc)</li>
</ul>
<p>And there is more. Because of these restrictions you can&#8217;t access a database! So you can&#8217;t use something like Hibernate and some Oracle/MySQL/Postgress machine. To still be able to save/persist objects Google has teamed up with Datanucleus. Using JDO or (a stripped down version of) JPA you can persist and retrieve objects on the cloud.</p>
<p>With this in mind I started making my own application. And the frameworks I wanted to use are:</p>
<ul>
<li>Wicket (Web Framework)</li>
<li>Spring IOC</li>
<li>Spring ORM (for transaction management, using annotations)</li>
<li>JPA (instead of the default JDO)</li>
</ul>
<p>The first problems I encountered was getting Wicket to load. Because of the sandbox-restrictions there are a couple of things you can&#8217;t do. For example, Wicket can&#8217;t save temporary data to disk (what it normally does). And there are problems with Wicket being in &#8216;development-mode&#8217; where is wants to start Threads to poll for changed resources.</p>
<p>A good overview on what it takes to get Wicket working is explained here:<br />
<a href="http://www.danwalmsley.com/2009/04/08/apache-wicket-on-google-app-engine-for-java/">http://www.danwalmsley.com/2009/04/08/apache-wicket-on-google-app-engine-for-java/</a></p>
<p>Next up was installing and running Spring. This was relatively easy at first. The core Spring code ran pretty much as expected. I added the JARs to my project and added this to the web.xml:</p>
<pre>
	&lt;!-- Spring --&gt;
	&lt;context-param&gt;
		&lt;param-name&gt;contextConfigLocation&lt;/param-name&gt;
		&lt;param-value&gt;classpath:applicationcontext-*.xml&lt;/param-value&gt;
	&lt;/context-param&gt;
	&lt;listener&gt;
		&lt;listener-class&gt;
			org.springframework.web.context.ContextLoaderListener
		&lt;/listener-class&gt;
	&lt;/listener&gt;
	&lt;listener&gt;
		&lt;listener-class&gt;
			org.springframework.web.context.request.RequestContextListener
		&lt;/listener-class&gt;
	&lt;/listener&gt;
</pre>
<p>As you can see, I load up multiple XML files. I decided to go with the all-out-annotations method using Spring ORM. This proved to be pretty challenging&#8230;</p>
<p>With these annotations you are able to do the following in the code:</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;">@<span style="color: #003399;">Repository</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;loginDao&quot;</span><span style="color: #009900;">&#41;</span>
@Transactional
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> LoginDaoImpl <span style="color: #000000; font-weight: bold;">implements</span> LoginDao <span style="color: #009900;">&#123;</span>
&nbsp;
	@PersistenceContext
	<span style="color: #000000; font-weight: bold;">private</span> EntityManager entityManager<span style="color: #339933;">;</span>
	... <span style="color: #009900;">&#40;</span>and more<span style="color: #009900;">&#41;</span></pre></div></div>

<p>As you can see I&#8217;m using Spring to inject my EntityManager into the DAO. But you can&#8217;t just load the entity manager in Google App Engine, you need a specific piece of configuration. I used the following XML:</p>
<pre>
	&lt;bean id=&quot;data.emf&quot;
		class=&quot;org.springframework.orm.jpa.LocalEntityManagerFactoryBean&quot;&gt;
		&lt;property name=&quot;persistenceUnitName&quot; value=&quot;transactions-optional&quot; /&gt;
	&lt;/bean&gt;

	&lt;bean class=&quot;org.springframework.orm.jpa.JpaTemplate&quot;&gt;
		&lt;property name=&quot;entityManagerFactory&quot; ref=&quot;data.emf&quot; /&gt;
	&lt;/bean&gt;

	&lt;bean id=&quot;transactionManager&quot;
		class=&quot;org.springframework.orm.jpa.JpaTransactionManager&quot;&gt;
		&lt;property name=&quot;entityManagerFactory&quot; ref=&quot;data.emf&quot; /&gt;
	&lt;/bean&gt;
</pre>
<p>To tell Spring to scan for these annotations you need to add the following lines in your applicationcontext:</p>
<pre>
	&lt;context:annotation-config /&gt;
	&lt;context:component-scan base-package=&quot;nl.redcode.*&quot; /&gt;
</pre>
<p>And now the problems start&#8230; The first problem is that Google App Engine doesn&#8217;t support all core classes. When loading these annotations Spring will load its PersistenceAnnotationBeanPostProcessor. But it contains the following piece of code:</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">try</span> <span style="color: #009900;">&#123;</span>
	<span style="color: #000000; font-weight: bold;">return</span> <span style="color: #009900;">&#40;</span>EntityManagerFactory<span style="color: #009900;">&#41;</span> lookup<span style="color: #009900;">&#40;</span>jndiName, EntityManagerFactory.<span style="color: #000000; font-weight: bold;">class</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
<span style="color: #000000; font-weight: bold;">catch</span> <span style="color: #009900;">&#40;</span><span style="color: #003399;">NamingException</span> ex<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	<span style="color: #000000; font-weight: bold;">throw</span> <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">IllegalStateException</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;Could not obtain 
		EntityManagerFactory [&quot;</span> <span style="color: #339933;">+</span> jndiName <span style="color: #339933;">+</span> <span style="color: #0000ff;">&quot;]from JNDI&quot;</span>, ex<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>And the Exception we get is:</p>
<pre>org.springframework.beans.factory.BeanCreationException: Error creating
bean with name
'org.springframework.context.annotation.internalPersistenceAnnotationProcessor':
Initialization of bean failed; nested exception is
java.lang.NoClassDefFoundError: javax/naming/NamingException
	at
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:480)
	at
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory$1.run(AbstractAutowireCapableBeanFactory.java:409)
	at java.security.AccessController.doPrivileged(Native Method)
	at
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:380)
	at
org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:264)
	at
...etc</pre>
<p>And when I looked at the white-list it was clear, NamingException isn&#8217;t part of the sandbox Google App Engine uses. So I started to google how to solve this. The first thing I encoutered was somebody who added the following lines to his/her applicationContext:</p>
<pre>
	&lt;bean id=&quot;org.springframework.context.annotation.internalPersistenceAnnotationProcessor&quot;
		class=&quot;java.lang.String&quot; /&gt;
</pre>
<p>This piece of code, when executed before the annotation-scan, loads a String in the Spring Container under the name &#8220;internalPersistenceAnnotationProcessor&#8221;. This causes Spring to ignore its own instantiation of the PersistenceAnnotationBeanPostProcessor and we don&#8217;t get the Exception anymore. </p>
<p>But this causes some more damage we don&#8217;t want in the application. Before my Dao&#8217;s received a valid EntityManager, but they are Null now&#8230;! </p>
<p>So I took the code of the original Spring PersistenceAnnotationBeanPostProcessor and replaced all the instances of NamingException with just Exception. This removed the dependency to NamingException. I called this new bean &#8220;AppEngineJPAPostProcessor&#8221;. This is how I configured it in the applicationContext:</p>
<pre>
	&lt;bean id=&quot;org.springframework.context.annotation.internalPersistenceAnnotationProcessor&quot;
		class=&quot;nl.redcode.springhack.AppEngineJPAPostProcessor&quot; /&gt;
</pre>
<p>The EntityManager(Factory) is now created, it gets injected into the DAO&#8217;s, they have transactions using annotations and everybody is happy!</p>
<p>When I got a little further in my project I decided to deploy my application to the cloud and test it online. Deploying your application to App Engine is very simple, just push the &#8220;Deploy&#8221; button in the Eclipse plugin and you only need to enter your credentials and a version-number of your release!</p>
<p>But then the old BeanPostProcessor bit me in the back again. On the server I got the following Exception when deploying:</p>
<pre>java.lang.SecurityException: Unable to get members for class org.springframework.jndi.JndiLocatorSupport
	at com.google.apphosting.runtime.security.shared.intercept.java.lang.Class_$10.run(Class_.java:357)
	at com.google.apphosting.runtime.security.shared.intercept.java.lang.Class_$10.run(Class_.java:347)
	at java.security.AccessController.doPrivileged(Native Method)
	at com.google.apphosting.runtime.security.shared.intercept.java.lang.Class_.getMembers(Class_.java:347)
	at com.google.apphosting.runtime.security.shared.intercept.java.lang.Class_.getDeclaredMethods(Class_.java:174)
	at org.springframework.util.ReflectionUtils.doWithMethods(ReflectionUtils.java:460)
	at org.springframework.util.ReflectionUtils.doWithMethods(ReflectionUtils.java:443)
	at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.findAutowiringMetadata(AutowiredAnnotationBeanPostProcessor.java:299)
	at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessMergedBeanDefinition(AutowiredAnnotationBeanPostProcessor.java:179)</pre>
<p>It seems the runtime is a bit more strict then the development server Google App Engine uses. For some reason it doesn&#8217;t like the JndiLocatorSupport. This is excepted because Google App Engine, due to the nature of the cloud, prohibits the use of JNDI.</p>
<p>Soon I found the problem, the only reference to JndiLocatorSupport is my own BeanPostProcessor:</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #008000; font-style: italic; font-weight: bold;">/**
 * Rewritten for use in Google AppEngine
 *
 * @author Roy van Rijn
 */</span>
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> AppEngineJPAPostProcessor <span style="color: #000000; font-weight: bold;">extends</span> JndiLocatorSupport <span style="color: #000000; font-weight: bold;">implements</span>
		InstantiationAwareBeanPostProcessor, BeanFactoryAware <span style="color: #009900;">&#123;</span>
&nbsp;
	<span style="color: #000000; font-weight: bold;">private</span> <span style="color: #003399;">Map</span> persistenceUnits<span style="color: #339933;">;</span>
	...</pre></div></div>

<p>When I removed the &#8216;extends&#8217; part there were two pieces of code that stopped working, they both look like this:</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;">	<span style="color: #000000; font-weight: bold;">try</span> <span style="color: #009900;">&#123;</span>
	<span style="color: #000000; font-weight: bold;">return</span> <span style="color: #009900;">&#40;</span>EntityManagerFactory<span style="color: #009900;">&#41;</span> lookup<span style="color: #009900;">&#40;</span>jndiName, EntityManagerFactory.<span style="color: #000000; font-weight: bold;">class</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>It seems this PostProcessor always does a JNDI lookup to find the correct EntityManager! But we can&#8217;t do this if we don&#8217;t have access to the JndiLocatorSupport methods anymore. So I decided to hack a little bit in this code, my solution was to load the EntityManagerFactory and EntityManager from the Spring container:</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">try</span> <span style="color: #009900;">&#123;</span>
	<span style="color: #000000; font-weight: bold;">return</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span>JpaTransactionManager<span style="color: #009900;">&#41;</span>beanFactory
		.<span style="color: #006633;">getBean</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;transactionManager&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
		.<span style="color: #006633;">getEntityManagerFactory</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #666666; font-style: italic;">/*	return (EntityManagerFactory) lookup(jndiName,
		EntityManagerFactory.class);*/</span>
<span style="color: #009900;">&#125;</span> <span style="color: #000000; font-weight: bold;">catch</span> <span style="color: #009900;">&#40;</span><span style="color: #003399;">Exception</span> ex<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
...</pre></div></div>

<p>This solved all the problems and with the changes to the BeanPostProcessor I&#8217;m now able to use all the Spring annotations, for persistency and transactions, in Google AppEngine.</p>
<p>I&#8217;m now still in the middle of developing my application on Google App Engine, but it seems that Google App Engine works like a charm. The problem is, most frameworks can&#8217;t really cope with the sandbox out-of-the-box. But with (some) minor patches and tweaking most frameworks will run using Google App Engine. The only major problem I&#8217;m having (which can&#8217;t be solved) is Datanucleus. I chose to use JPA because it is much richer and has more features then JDO, but Datanucleus hasn&#8217;t implemented much of these features yet.</p>
<p>For example, I had the following annotation on a field: <em>@Column(unique=true)</em><br />
Datanucleus threw &#8220;<em>java.lang.UnsupportedOperationException: No support for uniqueness<br />
constraints</em>&#8220;.</p>
<p>Also, I created a query with this: &#8220;<em>username = :username OR emailAddress = :emailAddress</em>&#8221;<br />
But Datanucleus doesn&#8217;t support the operator &#8220;OR&#8221;.</p>
<p>Other things DataNucleus can&#8217;t currently do:</p>
<ul>
<li>Many-to-many relationships</li>
<li>Joins in a query (WHAT??)</li>
<li>Aggregation queries (group by, having, sum, avg, max, min)</li>
<li>Polymorphic queries. You cannot perform a query of a class to get instances of a subclass. Each class is represented by a separate entity kind in the datastore.</li>
</ul>
<p>So, we&#8217;ve seen what a cloud is, what Google App Engine is, and I explained some tweaks/patches needed to get Wicket and Spring working.</p>
<p>Why use Google App Engine? It is free (up to some CPU/mail/data limits) and your project runs on a cloud, and thus is very scalable. You don&#8217;t have to worry about the environment or server. Your application will scale when its needed and everything is pre-installed and ready to run.<br />
But be prepared for difficult classloading issues and missing classes. You just can&#8217;t expect all frameworks to be working out-of-the-box with the sandbox-limitations. Also don&#8217;t expect much support with persisting, the JPA-support is very minimal and won&#8217;t let you do much more then persisting and retrieving single objects. </p>
<p>Enough blogging, now its time for me again to tinker on my application, maybe I&#8217;ll tell about it here in the future!</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.smart-java.nl/blog/index.php/2009/06/05/getting-on-the-cloud/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>Cyclische dependencies @ runtime</title>
		<link>http://blog.smart-java.nl/blog/index.php/2009/04/16/cyclische-dependencies-runtime/</link>
		<comments>http://blog.smart-java.nl/blog/index.php/2009/04/16/cyclische-dependencies-runtime/#comments</comments>
		<pubDate>Thu, 16 Apr 2009 11:01:40 +0000</pubDate>
		<dc:creator>Frank Verbruggen</dc:creator>
				<category><![CDATA[Architectuur]]></category>
		<category><![CDATA[Spring]]></category>
		<category><![CDATA[patterns]]></category>
		<category><![CDATA[spring]]></category>

		<guid isPermaLink="false">http://blog.smart-java.nl/blog/?p=353</guid>
		<description><![CDATA[In een gelaagd project zijn er meestal aparte lagen gedefinieerd voor services, domein logica en data access. Stel nu dat er een noodzaak is om vanuit een lager gelegen laag gebruik te maken van functionaliteit die thuis hoort in een hoger gelegen laag. Bijvoorbeeld omdat er in de domein objecten een noodzaak is om gebruik [...]]]></description>
			<content:encoded><![CDATA[<p>In een gelaagd project zijn er meestal aparte lagen gedefinieerd voor services, domein logica en data access. Stel nu dat er een noodzaak is om vanuit een lager gelegen laag gebruik te maken van functionaliteit die thuis hoort in een hoger gelegen laag. Bijvoorbeeld omdat er in de domein objecten een noodzaak is om gebruik te maken van een service. Hoe zorg je er dan voor dat je nette object georienteerde code houdt, zonder dat je compile time dependencies krijgt tussen je projecten / lagen? Het hier gepresenteerde design pattern is een elegante object georienteerde oplossing voor het bovenstaande probleem.</p>
<p>Gegeven een DomeinObject als object uit de lagere laag, en een ServiceImplementation als object uit de hogere laag. De serviceImplementation heeft een een interface methode &#8217;someMethod()&#8217; uit de ServiceInterface die benodigd is om de methode &#8216;businessMethod()&#8217; uit het DomeinObject te implementeren (zie figuur 1, originele klasse diagram).</p>
<p>N.B. Het design pattern is uitgewerkt met domein objecten en service implementaties, maar dat is slechts een invulling.</p>
<p>&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-<br />
<img src="http://blog.smart-java.nl/blog/wp-content/uploads/2009/04/originele-situatie.jpg" alt="" /><br />
&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-<br />
Figuur 1, originele klasse diagram<br />
&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-</p>
<p>Los dit als volgt op. Trek de ServiceInterface uit de hogere laag, en zet deze in de lagere laag. Maak een RequiredInterfaceFactory die een instantie van de ServiceInterface kan bevatten. Initialiseer bij het opstarten van je applicatie vanuit de bovenste laag de RequiredInterfaceFactory met de ServiceImplementation (dit kan bijvoorbeeld goed met de Spring configuratie uit Listing 1, Spring configuratie). En implementeer de businessMethod door de aanroep naar de ServiceImplementation als volgt te abstraheren:</p>

<div class="wp_syntax"><div class="code"><pre class="java5" style="font-family:monospace;">RequiredInterfaceFactory.<span style="color: #006633;">getInstance</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">getServiceInterface</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">someMethod</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Het klasse diagram ziet er dan uit zoals weergegeven in Figuur 2, klasse diagram.</p>
<p>&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-</p>

<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family:monospace;">&nbsp;</pre></div></div>

<p>&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-<br />
Listing 1, Spring configuratie<br />
&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-</p>
<p>&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-<br />
<img src="http://blog.smart-java.nl/blog/wp-content/uploads/2009/04/design-pattern.jpg" alt="" /><br />
&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-<br />
Figuur 2, klasse diagram<br />
&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-</p>
<p><strong>Voordelen en nadelen</strong></p>
<p>Het gebruik van dit design pattern biedt de volgende voordelen:</p>
<ul>
<li>Compile time dependencies zijn niet nodig</li>
<li>At runtime kunnen interface methoden van bovenliggende klassen toch gebruikt worden</li>
<li>Ieder object kan gebruik maken van de interface, ongeacht in welk package het zit, dus het ophalen van de interface kan in de code altijd op dezelfde manier gebeuren</li>
</ul>
<p>Het gebruik van dit design pattern biedt de volgende nadelen:</p>
<ul>
<li>Je moet de RequiredInterfaceFactory injecteren met de ServiceImplementation voordat de rest van de applicatie aangesproken wordt</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://blog.smart-java.nl/blog/index.php/2009/04/16/cyclische-dependencies-runtime/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Wat is er nieuw aan Model-Driven Development?</title>
		<link>http://blog.smart-java.nl/blog/index.php/2009/02/13/whats-new-about-model-driven-development/</link>
		<comments>http://blog.smart-java.nl/blog/index.php/2009/02/13/whats-new-about-model-driven-development/#comments</comments>
		<pubDate>Fri, 13 Feb 2009 16:10:12 +0000</pubDate>
		<dc:creator>Eric Jan Malotaux</dc:creator>
				<category><![CDATA[Model-driven Development]]></category>
		<category><![CDATA[Add new tag]]></category>

		<guid isPermaLink="false">http://blog.smart-java.nl/blog/?p=294</guid>
		<description><![CDATA[Toen de Object Management Group (OMG) in 2001 de Model Driven Architecture (MDA) introduceerde, veroorzaakte dat een golf van optimisme onder de relatief weinigen die zich nog met code-generatie bezig hielden. Eindelijk een standaard modelleertaal(UML), en dus uitwisseling van modellen tussen tools van verschillende leveranciers. Inmiddels is het enthousiasme voor het pure MDA vrijwel helemaal [...]]]></description>
			<content:encoded><![CDATA[<p>Toen de Object Management Group (OMG) in 2001 de Model Driven Architecture (MDA) introduceerde, veroorzaakte dat een golf van optimisme onder de relatief weinigen die zich nog met code-generatie bezig hielden. Eindelijk een standaard modelleertaal(UML), en dus uitwisseling van modellen tussen tools van verschillende leveranciers. Inmiddels is het enthousiasme voor het pure MDA vrijwel helemaal weggeëbt. Voornamelijk doordat UML nou niet ideaal bleek om behalve als modelleertaal, tegelijkertijd ook te dienen als basis voor het genereren van code. Te ingewikkeld, te groot, niet precies genoeg. En die standaardisatie bleek ook meer theorie dan praktijk. Om bruikbare code uit UML te kunnen genereren moest er nogal wat aan UML gesleuteld worden, dan deed iedere leverancier weer anders. Dus zeg maar dag tegen overdraagbare modellen!</p>
<p>Maar de laatste twee jaar komen de ideeën in een net even andere gedaante weer terug: nu op basis van Domain-Specific Languages (DSL&#8217;s). DSL&#8217;s zijn bezig in snel tempo enorm populair te worden. Overal wordt er mee geëxperimenteerd, en de conferenties over MDD schieten als paddestoelen uit de grond.  Hiervoor zijn verschillende oorzaken: (1)  DSL&#8217;s zijn veel kleiner en hanteerbaarder dan UML. (2) Het opkomen van tools als Microsoft DSL Tools, openArchitectureWare(oAW), en vooral xText, die het zelf maken van DSL&#8217;s binnen het bereik van &#8220;gewone&#8221; ontwikkelaars hebben gebracht. Grappig genoeg zijn al deze tools uiteindelijk in gebaseerd op één of andere gedaante van de Meta Object Facility (MOF), de kern van de MDA. Dit meta-metamodel standaardiseert het ontwikkelen van nieuwe metamodellen, en daarmee van nieuwe (modelleer)talen.  (3) DSL&#8217;s komen als geroepen. De complexiteit van de gemiddelde JEE applicatie neemt zo snel toe dat weinig ontwikkelaars het kunnen bijhouden. Aan de achterkant van een applicatie &#8211; de kant het dichtst bij de database &#8211; valt het nog wel mee: Hibernate is een blijvertje gebleken, al of niet in de incarnatie als JPA-implementatie. En ook het Spring-framework blijft een rots in de branding. Alhoewel, wat is nou beter: configuratie met XML bestanden of met annotaties? En Spring groeit ook als kool: wat moeten we met OSGi en Spring Integration. Maar aan de voorkant &#8211; de kant het dichtst bij de gebruiker &#8211; is de grote lijn helemaal zoek. Een jaar of acht geleden was Struts éénoog koning, maar nu moet je voor iedere applicatie kiezen tussen JSF, Wicket, GWT, Spring MVC of Webflow, of toch maar weer een Rich Client. En dan vergeten we voor het gemak even de technologieën die tussendoor nog even populair zijn geweest, zoals XML/XSLT. Het valt niet meer te behappen voor een gewoon mens, die &#8217;s-avonds ook nog wel eens een film wil zien in plaats van een tutorial (als dat er is tenminste) van weer een nieuw framework door te werken.</p>
<p>Model-driven Development op basis van DSL&#8217;s belooft een oplossing voor deze chaos. We ontwerpen een DSL voor het domein waarvoor we een applicatie maken, en een generator waar we de complexiteit in kunnen verstoppen. Daarvoor heb je dus nog wel een nerd nodig die al die ontwikkelingen wèl heeft kunnen bijbenen, maar de rest hoeft alleen maar de DSL te leren. En de nerd kan zich helemaal uitleven in de codegenerator, dus iedereen tevreden. Zou je zeggen.</p>
<p>Nou hebben we natuurlijk al vaker nieuwe ontwikkelingen meegemaakt die veel beloofden maar uiteindelijk teleurstelden. Object-oriëntatie, aspect-oriëntatie, agile development, test-driven development, whatever-driven-development, frameworks. Dus zo zal het met MDD ook wel weer gaan.  Toch hebben die nieuwe ontwikkelingen wel blijvende vooruitgang gebracht, alleen minder revolutionair dat we hadden gehoopt. Dus is de vraag, waarin ligt de echte verbetering van MDD, en waarin zal het tegenvallen.</p>
<p>Het ontwerpen van een DSL is moeilijk. Niet alleen de taal zelf, maar ook de benodigde tools om er een beetje lekker mee te kunnen werken. Dus zou het prettig zijn &#8216;m te kunnen hergebruiken. Daarom wordt vaak de applicatie architectuur als domein gekozen wordt in plaats van het domein van de gebruiker van de applicatie. Bij mod4j (http://www.mod4j.org/projectsite) bijvoorbeeld is dat gedaan. Maar de visie van de OMG &#8211; scheiden van pure business functionaliteit van implementatiedetails &#8211; wordt maar gedeeltelijk bereikt.  Want we moeten de applicatie specificeren in termen van de applicatie architectuur in plaats van concepten die betekenis hebben voor de klant. We maken wel modellen, maar sinds het verschijnen van tekst-gebaseerde tools als xText kunnen we die net zo goed maken in tekstuele vorm als in diagram vorm.  Wat is dan nog het verschil tussen een model en een programma?  Eigenlijk geen.  Vandaar dat Anneke Kleppe in haar nieuwe boek &#8220;Software Language Engineering: Creating Domain-Specific Languages Using Metamodels&#8221; de term &#8220;mogram&#8221; introduceert.</p>
<p>Wat is dan eigenlijk nieuw? Eenvoudig dit: met een DSL werkt een programmeur op een hoger abstractieniveau. Hij heeft met minder concepten te maken dan met puur Java. Dat resulteert in veel compactere code. Bij mod4j bijvoorbeeld worden er per regel DSL-code bijna 25 regels Java- en XML-code gegenereerd. Volgens Frederick Brooke in zijn boek &#8220;The Mythical Man Month&#8221; is de productiviteit van een programmeur constant in termen van het aantal statements per tijdseenheid. Mod4j is nog niet in de praktijk beproefd, dus wat de winst echt is moet nog blijken. Hoopgevend is het in elk geval wel.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.smart-java.nl/blog/index.php/2009/02/13/whats-new-about-model-driven-development/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>JBoss Envers</title>
		<link>http://blog.smart-java.nl/blog/index.php/2008/12/30/jboss-envers/</link>
		<comments>http://blog.smart-java.nl/blog/index.php/2008/12/30/jboss-envers/#comments</comments>
		<pubDate>Tue, 30 Dec 2008 12:05:35 +0000</pubDate>
		<dc:creator>jeroen weelink</dc:creator>
				<category><![CDATA[Tools/Frameworks]]></category>

		<guid isPermaLink="false">http://blog.smart-java.nl/blog/?p=279</guid>
		<description><![CDATA[Auditing is een van de belangrijkste onderdelen in ieder systeem. Er zijn al enkele manieren om dit te regelen. Het makkelijkste is een audit log, Gerry Noij is nu bezig met het beschrijven van het temporal object pattern.
JBoss heeft sinds dit jaar een nieuw project erbij: Envers. Annoteer je de classes of properties met @Versioned, [...]]]></description>
			<content:encoded><![CDATA[<p>Auditing is een van de belangrijkste onderdelen in ieder systeem. Er zijn al enkele manieren om dit te regelen. Het makkelijkste is een <a title="Audit log" href="http://martinfowler.com/ap2/auditLog.html" target="_blank">audit log</a>, Gerry Noij is nu bezig met het beschrijven van het <a title="Deel 1 van de reeks" href="http://blog.smart-java.nl/blog/index.php/2008/11/19/temporale-data-%e2%80%93-deel-1-de-concepten/" target="_self">temporal object pattern</a>.</p>
<p>JBoss heeft sinds dit jaar een nieuw project erbij: <a title="Homepage van Envers" href="http://www.jboss.org/envers/" target="_blank">Envers</a>. Annoteer je de classes of properties met @Versioned, dan wordt de rest voor je geregeld. <em><br />
</em></p>
<blockquote><p><em> The Envers project aims to enable easy versioning of persistent classes.  All that you have to do is annotate your persistent class or some of its properties, that you want to version, with <strong><code>@Versioned</code></strong>.  For each versioned entity, a table will be created, which will hold the history of changes made to the entity. You can then retrieve and query historical data without much effort.</em></p></blockquote>
<p>Om een voorbeeld te geven hoe je classes er in het vervolg uitzien, een klein stukje overgenomen van de quickstart.</p>
<p>Class Person:</p>
<pre>import org.jboss.versions.Versioned;  

import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.GeneratedValue;
import javax.persistence.Column;  

@Entity
@Versioned // that's the important part
public class Person {
    @Id
    @GeneratedValue
    private int id;  

    private String name;  

    private String surname;  

    @ManyToOne
    private Address address;  

    // add getters, setters, constructors, equals and hashCode here
}</pre>
<ol class="dp-j"></ol>
<p><span>Class Address:<br />
</span></p>
<pre>@Entity
@Versioned
public class Address {
    @Id
    @GeneratedValue
    private int id;  

    private String streetName;  

    private Integer houseNumber;  

    private Integer flatNumber;  

    @OneToMany(mappedBy = "address")
    private Set&lt;Person&gt; persons;  

    // add getters, setters, constructors, equals and hashCode here
}</pre>
<p>Daarnaast moeten er 6 listeners worden geregistreerd. Als je het schema laat genereren, worden er 2 extra tabellen aangemaakt: address_versions en person_versions en deze worden automatisch gevuld met historische data. Het ophalen van een specifieke versie gebeurt met een VersionReader:</p>
<pre><span><span>VersionsReader reader = VersionsReaderFactory.get(entityManager);
</span>Person oldPerson = reader.find(Person.<span class="keyword">class</span><span>, personId, revision); </span></span></pre>
<pre><span></span></pre>
<p>Het is mij net bekend geworden dat dit bestaat, ik heb zelf geen ervaring met Envers. Misschien dat anderen dat wel hebben?</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.smart-java.nl/blog/index.php/2008/12/30/jboss-envers/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Temporale data – deel 3: het bitemporale pattern</title>
		<link>http://blog.smart-java.nl/blog/index.php/2008/12/22/temporale-data-%e2%80%93-deel-3-het-bitemporale-pattern/</link>
		<comments>http://blog.smart-java.nl/blog/index.php/2008/12/22/temporale-data-%e2%80%93-deel-3-het-bitemporale-pattern/#comments</comments>
		<pubDate>Mon, 22 Dec 2008 12:18:04 +0000</pubDate>
		<dc:creator>gnoij</dc:creator>
				<category><![CDATA[Tools/Frameworks]]></category>
		<category><![CDATA[patterns]]></category>
		<category><![CDATA[bitemporal pattern]]></category>
		<category><![CDATA[temporal data]]></category>

		<guid isPermaLink="false">http://blog.smart-java.nl/blog/?p=275</guid>
		<description><![CDATA[In dit derde deel van de serie over temporale data breidt ik het temporale pattern uit het tweede deel uit met de registratietijd voor opvoer en afvoer. Hierdoor ontstaat het bitemporale pattern.
BiTemporalObject

public abstract class BiTemporalObject implements Cloneable &#123;
&#160;
    private Date ingangsdatum;
&#160;
    private Date einddatum;
&#160;
    private Date [...]]]></description>
			<content:encoded><![CDATA[<p>In dit derde deel van de serie over temporale data breidt ik het temporale pattern uit het <a href="http://blog.smart-java.nl/blog/index.php/2008/12/07/temporale-data-%E2%80%93-deel-2-het-temporale-pattern/">tweede deel</a> uit met de registratietijd voor opvoer en afvoer. Hierdoor ontstaat het bitemporale pattern.</p>
<p><strong>BiTemporalObject</strong></p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">abstract</span> <span style="color: #000000; font-weight: bold;">class</span> BiTemporalObject <span style="color: #000000; font-weight: bold;">implements</span> <span style="color: #003399;">Cloneable</span> <span style="color: #009900;">&#123;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #003399;">Date</span> ingangsdatum<span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #003399;">Date</span> einddatum<span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #003399;">Date</span> opvoerTijdstip<span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #003399;">Date</span> afvoerTijdstip<span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">protected</span> BiTemporalObject<span style="color: #009900;">&#40;</span><span style="color: #003399;">Date</span> ingangsdatum<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">super</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>ingangsdatum <span style="color: #339933;">==</span> <span style="color: #000066; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #000000; font-weight: bold;">throw</span> <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">IllegalArgumentException</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;Ingangsdatum is null&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
&nbsp;
        <span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">ingangsdatum</span> <span style="color: #339933;">=</span> ingangsdatum<span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">opvoerTijdstip</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">Date</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">boolean</span> isGeldigOp<span style="color: #009900;">&#40;</span><span style="color: #003399;">Date</span> registratieTijdstip, <span style="color: #003399;">Date</span> peilDatum<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">return</span> isGeregistreerdOp<span style="color: #009900;">&#40;</span>registratieTijdstip<span style="color: #009900;">&#41;</span> <span style="color: #339933;">&amp;&amp;</span> isGeldigOp<span style="color: #009900;">&#40;</span>peilDatum<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000066; font-weight: bold;">boolean</span> isGeregistreerdOp<span style="color: #009900;">&#40;</span><span style="color: #003399;">Date</span> registratieTijdstip<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #339933;">!</span>isAfgevoerd<span style="color: #009900;">&#40;</span>registratieTijdstip<span style="color: #009900;">&#41;</span>
                <span style="color: #339933;">&amp;&amp;</span> <span style="color: #009900;">&#40;</span>registratieTijdstip.<span style="color: #006633;">after</span><span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">opvoerTijdstip</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">||</span> registratieTijdstip.<span style="color: #006633;">equals</span><span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">opvoerTijdstip</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000066; font-weight: bold;">boolean</span> isAfgevoerd<span style="color: #009900;">&#40;</span><span style="color: #003399;">Date</span> registratieTijdstip<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">afvoerTijdstip</span> <span style="color: #339933;">!=</span> <span style="color: #000066; font-weight: bold;">null</span> <span style="color: #339933;">&amp;&amp;</span> <span style="color: #009900;">&#40;</span>registratieTijdstip.<span style="color: #006633;">after</span><span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">afvoerTijdstip</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">||</span> registratieTijdstip.<span style="color: #006633;">equals</span><span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">afvoerTijdstip</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000066; font-weight: bold;">boolean</span> isGeldigOp<span style="color: #009900;">&#40;</span><span style="color: #003399;">Date</span> peilDatum<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000066; font-weight: bold;">boolean</span> geldig <span style="color: #339933;">=</span> peilDatum.<span style="color: #006633;">after</span><span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">ingangsdatum</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">||</span> peilDatum.<span style="color: #006633;">equals</span><span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">ingangsdatum</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">einddatum</span> <span style="color: #339933;">!=</span> <span style="color: #000066; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            geldig <span style="color: #339933;">=</span> geldig <span style="color: #339933;">&amp;&amp;</span> peilDatum.<span style="color: #006633;">before</span><span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">einddatum</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
        <span style="color: #000000; font-weight: bold;">return</span> geldig<span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">protected</span> BiTemporalObject kopieer<span style="color: #009900;">&#40;</span><span style="color: #003399;">Date</span> wijzigingsdatum, <span style="color: #003399;">Date</span> registratieTijdstip<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #666666; font-style: italic;">// maak een kopie met gevulde einddatum</span>
        BiTemporalObject versie <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span>BiTemporalObject<span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">super</span>.<span style="color: #006633;">kopieer</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        versie.<span style="color: #006633;">opvoerTijdstip</span> <span style="color: #339933;">=</span> registratieTijdstip<span style="color: #339933;">;</span>
        versie.<span style="color: #006633;">afvoerTijdstip</span> <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">null</span><span style="color: #339933;">;</span>
        versie.<span style="color: #006633;">einddatum</span> <span style="color: #339933;">=</span> wijzigingsdatum<span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #666666; font-style: italic;">// voer de oude versie af</span>
        <span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">afvoerTijdstip</span> <span style="color: #339933;">=</span> registratieTijdstip<span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #000000; font-weight: bold;">return</span> versie<span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #003399;">Date</span> getIngangsdatum<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">ingangsdatum</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #003399;">Date</span> getEinddatum<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">einddatum</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #003399;">Date</span> getOpvoerTijdstip<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">opvoerTijdstip</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #003399;">Date</span> getAfvoerTijdstip<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">afvoerTijdstip</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span></pre></div></div>

</p>
<p>In deze klasse vallen (ten opzichte van <code>TemporalObject</code>) een aantal dingen op. Allereerst dat deze klasse <code>clonable</code> is, verder dat een object pas geldig is als de registratietijd binnen de opvoer en afvoer registratie is en dat er een <code>kopieer</code> methode is, die een kopie (clone) van het object maakt met de huidige opvoertijd en einddatum. Het oorspronkelijke object wordt dan afgevoerd door het vullen van de afvoer registratietijd. Bij creatie van een <code>BiTemporalObject </code>wordt automatisch het opvoertijdstip gevuld met de systeemdatum.</p>
<p><strong>BiTemporalProperty</strong></p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> BiTemporalProperty <span style="color: #009900;">&#123;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">protected</span> <span style="color: #003399;">List</span> alleHistorischeVersies <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">ArrayList</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> BiTemporalProperty<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">super</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> BiTemporalObject getActueleVersie<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">return</span> getVersieOp<span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">Date</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>, <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">Date</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> BiTemporalObject getVersieOp<span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">final</span> <span style="color: #003399;">Date</span> registratieTijdstip, <span style="color: #000000; font-weight: bold;">final</span> <span style="color: #003399;">Date</span> peilDatum<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #009900;">&#40;</span>BiTemporalObject<span style="color: #009900;">&#41;</span> CollectionUtils.<span style="color: #006633;">find</span><span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">alleHistorischeVersies</span>, <span style="color: #000000; font-weight: bold;">new</span> Predicate<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">boolean</span> evaluate<span style="color: #009900;">&#40;</span><span style="color: #003399;">Object</span> object<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
                <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span>BiTemporalObject<span style="color: #009900;">&#41;</span> object<span style="color: #009900;">&#41;</span>.<span style="color: #006633;">isGeldigOp</span><span style="color: #009900;">&#40;</span>registratieTijdstip, peilDatum<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
            <span style="color: #009900;">&#125;</span>
        <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> setActueleVersie<span style="color: #009900;">&#40;</span>BiTemporalObject actueleVersie<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>actueleVersie <span style="color: #339933;">==</span> <span style="color: #000066; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #000000; font-weight: bold;">throw</span> <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">IllegalArgumentException</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;actueleVersie is null&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
&nbsp;
        beeindigVorigeVersie<span style="color: #009900;">&#40;</span>actueleVersie<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">alleHistorischeVersies</span>.<span style="color: #006633;">add</span><span style="color: #009900;">&#40;</span>actueleVersie<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000066; font-weight: bold;">void</span> beeindigVorigeVersie<span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">final</span> BiTemporalObject actueleVersie<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        BiTemporalObject afTeVoerenVersie <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span>BiTemporalObject<span style="color: #009900;">&#41;</span> CollectionUtils.<span style="color: #006633;">find</span><span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">alleHistorischeVersies</span>, <span style="color: #000000; font-weight: bold;">new</span> Predicate<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">boolean</span> evaluate<span style="color: #009900;">&#40;</span><span style="color: #003399;">Object</span> object<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
                BiTemporalObject versie <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span>BiTemporalObject<span style="color: #009900;">&#41;</span> object<span style="color: #339933;">;</span>
                <span style="color: #000000; font-weight: bold;">return</span> versie.<span style="color: #006633;">isGeldigOp</span><span style="color: #009900;">&#40;</span>actueleVersie.<span style="color: #006633;">getOpvoerTijdstip</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>, actueleVersie.<span style="color: #006633;">getIngangsdatum</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
            <span style="color: #009900;">&#125;</span>
        <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>afTeVoerenVersie <span style="color: #339933;">!=</span> <span style="color: #000066; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            BiTemporalObject kopieVersie <span style="color: #339933;">=</span> afTeVoerenVersie.<span style="color: #006633;">kopieer</span><span style="color: #009900;">&#40;</span>actueleVersie.<span style="color: #006633;">getIngangsdatum</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>, actueleVersie.<span style="color: #006633;">getOpvoerTijdstip</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
            <span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">alleHistorischeVersies</span>.<span style="color: #006633;">add</span><span style="color: #009900;">&#40;</span>kopieVersie<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> beeindig<span style="color: #009900;">&#40;</span><span style="color: #003399;">Date</span> einddatum<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        BiTemporalObject teBeeindigenVersie <span style="color: #339933;">=</span> getActueleVersie<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>teBeeindigenVersie <span style="color: #339933;">!=</span> <span style="color: #000066; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            BiTemporalObject kopieVersie <span style="color: #339933;">=</span> teBeeindigenVersie.<span style="color: #006633;">kopieer</span><span style="color: #009900;">&#40;</span>einddatum, <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">Date</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
            <span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">alleHistorischeVersies</span>.<span style="color: #006633;">add</span><span style="color: #009900;">&#40;</span>kopieVersie<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

</p>
<p>Het verschil van de <code>BiTemporalProperty</code> met de <code>TemporalProperty</code> is dat er nu twee tijdstippen worden meegegeven om de juiste versie te bepalen. Naast de peildatum is dat ook het registratietijdstip. Als er een actuele versie wordt toegevoegd of beëindigd, wordt de op dat moment geldende versie gekopieerd en afgevoerd. De gekopieerde versie wordt beëindigd. Hierdoor zal er altijd bij beëindiging of wijziging een extra record ontstaan. Dit wordt verklaard in de concepten voor bitemporale data in <a href="http://blog.smart-java.nl/blog/index.php/2008/11/19/temporale-data-%E2%80%93-deel-1-de-concepten/">deel 1</a>.</p>
<h3>Een voorbeeld</h3>
<p>We gebruiken hier hetzelfde voorbeeld als uit deel 2. </p>
<p><strong>Werknemer</strong></p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> Werknemer <span style="color: #009900;">&#123;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">private</span> BiTemporalProperty afdelingRelatie <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> BiTemporalProperty<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #003399;">String</span> naam<span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> Werknemer<span style="color: #009900;">&#40;</span><span style="color: #003399;">String</span> naam<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">super</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">naam</span> <span style="color: #339933;">=</span> naam<span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #003399;">String</span> getNaam<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">naam</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> setAfdeling<span style="color: #009900;">&#40;</span>Afdeling afdeling, <span style="color: #003399;">Date</span> ingangsdatum<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">afdelingRelatie</span>.<span style="color: #006633;">setActueleVersie</span><span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">new</span> AfdelingRelatie<span style="color: #009900;">&#40;</span>afdeling, ingangsdatum<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> Afdeling getAfdeling<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        AfdelingRelatie relatie <span style="color: #339933;">=</span> getAfdelingRelatie<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>relatie <span style="color: #339933;">!=</span> <span style="color: #000066; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #000000; font-weight: bold;">return</span> relatie.<span style="color: #006633;">getAfdeling</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
        <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #000066; font-weight: bold;">null</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> Afdeling getAfdeling<span style="color: #009900;">&#40;</span><span style="color: #003399;">Date</span> registratieTijdstip, <span style="color: #003399;">Date</span> peildatum<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        AfdelingRelatie relatie <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span>AfdelingRelatie<span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">afdelingRelatie</span>.<span style="color: #006633;">getVersieOp</span><span style="color: #009900;">&#40;</span>registratieTijdstip, peildatum<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>relatie <span style="color: #339933;">!=</span> <span style="color: #000066; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #000000; font-weight: bold;">return</span> relatie.<span style="color: #006633;">getAfdeling</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
        <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #000066; font-weight: bold;">null</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> AfdelingRelatie getAfdelingRelatie<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #009900;">&#40;</span>AfdelingRelatie<span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">afdelingRelatie</span>.<span style="color: #006633;">getActueleVersie</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> AfdelingRelatie getAfdelingRelatie<span style="color: #009900;">&#40;</span><span style="color: #003399;">Date</span> registratieTijdstip, <span style="color: #003399;">Date</span> peildatum<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #009900;">&#40;</span>AfdelingRelatie<span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">afdelingRelatie</span>.<span style="color: #006633;">getVersieOp</span><span style="color: #009900;">&#40;</span>registratieTijdstip, peildatum<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> uitDienst<span style="color: #009900;">&#40;</span><span style="color: #003399;">Date</span> datumUitdienst<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">afdelingRelatie</span>.<span style="color: #006633;">beeindig</span><span style="color: #009900;">&#40;</span>datumUitdienst<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

</p>
<p>Ten opzichte van de klasse <code>Werknemer</code> uit deel 2 hebben de methoden <code>getAfdeling</code> en <code>getAfdelingRelatie</code> een extra parameter <code>registratieTijdstip</code>. </p>
<p><strong>AfdelingRelatie</strong></p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> AfdelingRelatie <span style="color: #000000; font-weight: bold;">extends</span> BiTemporalObject <span style="color: #009900;">&#123;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">private</span> Afdeling afdeling<span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">protected</span> AfdelingRelatie<span style="color: #009900;">&#40;</span>Afdeling afdeling, <span style="color: #003399;">Date</span> ingangsdatum<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">super</span><span style="color: #009900;">&#40;</span>ingangsdatum<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">afdeling</span> <span style="color: #339933;">=</span> afdeling<span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> Afdeling getAfdeling<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">afdeling</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Deze klasse <code>AfdelingRelatie</code> is afgeleid van de klasse <code>BiTemporalObject</code>. Verder is deze analoog aan de klasse uit deel 2. </p>
<p>De klasse Afdeling is analoog aan de klasse Afdeling uit deel 2.</p>
<p> De test ziet er als volgt uit:</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;">    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> testWerknemer<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        Werknemer werknemer <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Werknemer<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;Kees&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #666666; font-style: italic;">// simuleer de opvoer tijd 1-1-2003</span>
        BiTemporalObject.<span style="color: #006633;">TEST_OPVOER_TIJDSTIP</span> <span style="color: #339933;">=</span> DateUtils.<span style="color: #006633;">maakDate</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">2003</span>, <span style="color: #cc66cc;">1</span>, <span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        Afdeling inkoop <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Afdeling<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;Inkoop&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        werknemer.<span style="color: #006633;">setAfdeling</span><span style="color: #009900;">&#40;</span>inkoop, DateUtils.<span style="color: #006633;">maakDate</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">2003</span>, <span style="color: #cc66cc;">1</span>, <span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #666666; font-style: italic;">// simuleer de opvoer tijd 1-2-2006</span>
        BiTemporalObject.<span style="color: #006633;">TEST_OPVOER_TIJDSTIP</span> <span style="color: #339933;">=</span> DateUtils.<span style="color: #006633;">maakDate</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">2006</span>, <span style="color: #cc66cc;">2</span>, <span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        Afdeling verkoop <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Afdeling<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;Verkoop&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        werknemer.<span style="color: #006633;">setAfdeling</span><span style="color: #009900;">&#40;</span>verkoop, DateUtils.<span style="color: #006633;">maakDate</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">2006</span>, <span style="color: #cc66cc;">1</span>, <span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        assertEquals<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;Kees&quot;</span>, werknemer.<span style="color: #006633;">getNaam</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        assertEquals<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;Verkoop&quot;</span>, werknemer.<span style="color: #006633;">getAfdeling</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">getNaam</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        assertEquals<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;Verkoop&quot;</span>, werknemer.<span style="color: #006633;">getAfdeling</span><span style="color: #009900;">&#40;</span>DateUtils.<span style="color: #006633;">vandaag</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>, DateUtils.<span style="color: #006633;">maakDate</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">2006</span>, <span style="color: #cc66cc;">1</span>, <span style="color: #cc66cc;">15</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">getNaam</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        assertEquals<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;Inkoop&quot;</span>, werknemer.<span style="color: #006633;">getAfdeling</span><span style="color: #009900;">&#40;</span>DateUtils.<span style="color: #006633;">maakDate</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">2006</span>, <span style="color: #cc66cc;">1</span>, <span style="color: #cc66cc;">15</span><span style="color: #009900;">&#41;</span>, DateUtils.<span style="color: #006633;">maakDate</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">2006</span>, <span style="color: #cc66cc;">1</span>, <span style="color: #cc66cc;">15</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">getNaam</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #666666; font-style: italic;">// simuleer de opvoer tijd 1-2-2008</span>
        BiTemporalObject.<span style="color: #006633;">TEST_OPVOER_TIJDSTIP</span> <span style="color: #339933;">=</span> DateUtils.<span style="color: #006633;">maakDate</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">2008</span>, <span style="color: #cc66cc;">2</span>, <span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        werknemer.<span style="color: #006633;">uitDienst</span><span style="color: #009900;">&#40;</span>DateUtils.<span style="color: #006633;">maakDate</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">2008</span>, <span style="color: #cc66cc;">1</span>, <span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        assertNull<span style="color: #009900;">&#40;</span>werknemer.<span style="color: #006633;">getAfdeling</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span></pre></div></div>

<p>In deze test maken we een werknemer Kees aan, die begint te werken op de afdeling Inkoop op 1 januari 2003. Dit wordt op dezelfde datum geregistreerd. Vanaf 1 januari 2006 werkt Kees op de afdeling Verkoop, wat pas op 1 februari wordt geregistreerd en vanaf  1 januari 2008 is Kees uit dienst. Dit wordt een maand later pas geregistreerd.</p>
<p>Omdat de registratietijd automatisch wordt bepaald heb ik (uitsluitend voor testdoeleinden) de klasse BiTemporalObject uitgebreid met een public static member <code>TEST_OPVOER_TIJDSTIP</code>, om de registratietijd uit het voorbeeld te kunnen simuleren. Hierdoor verandert de constructor van <code>BiTemporalObject</code> in</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;">    <span style="color: #000000; font-weight: bold;">protected</span> BiTemporalObject<span style="color: #009900;">&#40;</span><span style="color: #003399;">Date</span> ingangsdatum<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">super</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>ingangsdatum <span style="color: #339933;">==</span> <span style="color: #000066; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #000000; font-weight: bold;">throw</span> <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">IllegalArgumentException</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;Ingangsdatum is null&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
&nbsp;
        <span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">ingangsdatum</span> <span style="color: #339933;">=</span> ingangsdatum<span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #666666; font-style: italic;">// voor testdoeleinden</span>
        <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>TEST_OPVOER_TIJDSTIP <span style="color: #339933;">==</span> <span style="color: #000066; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">opvoerTijdstip</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">Date</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span> <span style="color: #000000; font-weight: bold;">else</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">opvoerTijdstip</span> <span style="color: #339933;">=</span> TEST_OPVOER_TIJDSTIP<span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
    <span style="color: #009900;">&#125;</span></pre></div></div>

</p>
<h3>Hibernate mappings</h3>
<p>De hibernate mapping van de klasse <code>Werknemer</code> en <code>Afdeling</code> zijn analoog aan die van de klasse <code>Werknemer</code> uit deel 2.<br />
De mapping van de klasse <code>AfdelingRelatie</code> is uitgebreid met de opvoer- en afvoer registratietijd. </p>
<p><strong>AfdelingRelatie</strong></p>

<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;hibernate-mapping</span> <span style="color: #000066;">package</span>=<span style="color: #ff0000;">&quot;nl.ordina.bitemporal.example&quot;</span></span>
<span style="color: #009900;">	<span style="color: #000066;">default-access</span>=<span style="color: #ff0000;">&quot;field&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
	<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;class</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;AfdelingRelatie&quot;</span> <span style="color: #000066;">table</span>=<span style="color: #ff0000;">&quot;AfdelingRelatie&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
		<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;id</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;id&quot;</span> <span style="color: #000066;">column</span>=<span style="color: #ff0000;">&quot;id&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
			<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;generator</span> <span style="color: #000066;">class</span>=<span style="color: #ff0000;">&quot;identity&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span><span style="color: #000000; font-weight: bold;">&lt;/generator<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
		<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/id<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
		<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;version</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;versie&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
&nbsp;
		<span style="color: #808080; font-style: italic;">&lt;!-- temporale informatie --&gt;</span>
		<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;property</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;ingangsdatum&quot;</span> <span style="color: #000066;">type</span>=<span style="color: #ff0000;">&quot;date&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
		<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;property</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;einddatum&quot;</span> <span style="color: #000066;">type</span>=<span style="color: #ff0000;">&quot;date&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
		<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;property</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;opvoerTijdstip&quot;</span> <span style="color: #000066;">type</span>=<span style="color: #ff0000;">&quot;date&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
		<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;property</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;afvoerTijdstip&quot;</span> <span style="color: #000066;">type</span>=<span style="color: #ff0000;">&quot;date&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
&nbsp;
		<span style="color: #808080; font-style: italic;">&lt;!-- de verwijzing naar de afdeling --&gt;</span>
		<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;many-to-one</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;afdeling&quot;</span> <span style="color: #000066;">lazy</span>=<span style="color: #ff0000;">&quot;false&quot;</span> <span style="color: #000066;">class</span>=<span style="color: #ff0000;">&quot;Afdeling&quot;</span></span>
<span style="color: #009900;">			<span style="color: #000066;">column</span>=<span style="color: #ff0000;">&quot;afdelingId&quot;</span> <span style="color: #000066;">cascade</span>=<span style="color: #ff0000;">&quot;none&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
	<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/class<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/hibernate-mapping<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></div></div>

<p>Het volgende deel zal het bitemporale pattern uitbreiden met historische collections.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.smart-java.nl/blog/index.php/2008/12/22/temporale-data-%e2%80%93-deel-3-het-bitemporale-pattern/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Temporale data – deel 2: het temporale pattern</title>
		<link>http://blog.smart-java.nl/blog/index.php/2008/12/07/temporale-data-%e2%80%93-deel-2-het-temporale-pattern/</link>
		<comments>http://blog.smart-java.nl/blog/index.php/2008/12/07/temporale-data-%e2%80%93-deel-2-het-temporale-pattern/#comments</comments>
		<pubDate>Sun, 07 Dec 2008 11:32:49 +0000</pubDate>
		<dc:creator>gnoij</dc:creator>
				<category><![CDATA[Tools/Frameworks]]></category>
		<category><![CDATA[patterns]]></category>
		<category><![CDATA[historie]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[temporal pattern]]></category>

		<guid isPermaLink="false">http://blog.smart-java.nl/blog/?p=267</guid>
		<description><![CDATA[Zoals al in het eerste deel te zien was is temporale data op te delen in temporale (alleen geldigheid) of bitemporale data (geldigheid met registratietijd). In dit tweede deel beschrijf ik het pattern voor temporale data.
De kern van dit pattern zijn de Java klassen TemporalObject en TemporalProperty. TemporalObject bevat de logica voor de geldigheid en [...]]]></description>
			<content:encoded><![CDATA[<p>Zoals al in het <a href="http://blog.smart-java.nl/blog/index.php/2008/11/19/temporale-data-%E2%80%93-deel-1-de-concepten/">eerste deel</a> te zien was is temporale data op te delen in temporale (alleen geldigheid) of bitemporale data (geldigheid met registratietijd). In dit tweede deel beschrijf ik het pattern voor temporale data.</p>
<p>De kern van dit pattern zijn de Java klassen <tt>TemporalObject</tt> en <tt>TemporalProperty</tt>. <tt>TemporalObject</tt> bevat de logica voor de geldigheid en <tt>TemporalProperty</tt> bevat de code om een de juiste versie van een property te kunnen bepalen.</p>
<p>
<b>TemporalObject</b></p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">abstract</span> <span style="color: #000000; font-weight: bold;">class</span> TemporalObject <span style="color: #009900;">&#123;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #003399;">Date</span> ingangsdatum<span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #003399;">Date</span> einddatum<span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">protected</span> TemporalObject<span style="color: #009900;">&#40;</span><span style="color: #003399;">Date</span> ingangsdatum<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">super</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>ingangsdatum <span style="color: #339933;">==</span> <span style="color: #000066; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #000000; font-weight: bold;">throw</span> <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">IllegalArgumentException</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;Ingangsdatum is verplicht&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
&nbsp;
        <span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">ingangsdatum</span> <span style="color: #339933;">=</span> ingangsdatum<span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">boolean</span> isGeldigOp<span style="color: #009900;">&#40;</span><span style="color: #003399;">Date</span> peildatum<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000066; font-weight: bold;">boolean</span> geldig <span style="color: #339933;">=</span> peildatum.<span style="color: #006633;">after</span><span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">ingangsdatum</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">||</span> peildatum.<span style="color: #006633;">equals</span><span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">ingangsdatum</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">einddatum</span> <span style="color: #339933;">!=</span> <span style="color: #000066; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            geldig <span style="color: #339933;">=</span> geldig <span style="color: #339933;">&amp;&amp;</span> peildatum.<span style="color: #006633;">before</span><span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">einddatum</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
        <span style="color: #000000; font-weight: bold;">return</span> geldig<span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #003399;">Date</span> getIngangsdatum<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">ingangsdatum</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #003399;">Date</span> getEinddatum<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">einddatum</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> beeindig<span style="color: #009900;">&#40;</span><span style="color: #003399;">Date</span> einddatum<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">einddatum</span> <span style="color: #339933;">=</span> einddatum<span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

</p>
<p>Deze klasse is de superklasse van een klasse met geldigheid. Deze klasse bevat de ingangsdatum en einddatum van een versie. Deze klasse bevat alleen een constructor met ingangsdatum, omdat deze verplicht is (anders kunnen we geen historie bijhouden). Verder kent deze klasse de methode om de te vragen of een object geldig is op een bepaalde datum en een methode om een instantie te kunnen beëindigen. Deze klasse is gebaseerd op het <a href="http://www.martinfowler.com/eaaDev/Effectivity.html">Effectivity Pattern</a> van Martin Fowler. </p>
<p>
<b>TemporalProperty</b></p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> TemporalProperty <span style="color: #009900;">&#123;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">protected</span> <span style="color: #003399;">List</span> alleHistorischeVersies <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">ArrayList</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> TemporalProperty<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">super</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> TemporalObject getActueleVersie<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">return</span> getVersieOp<span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">Date</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> TemporalObject getVersieOp<span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">final</span> <span style="color: #003399;">Date</span> peildatum<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #009900;">&#40;</span>TemporalObject<span style="color: #009900;">&#41;</span> CollectionUtils.<span style="color: #006633;">find</span><span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">alleHistorischeVersies</span>, <span style="color: #000000; font-weight: bold;">new</span> Predicate<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">boolean</span> evaluate<span style="color: #009900;">&#40;</span><span style="color: #003399;">Object</span> object<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
                <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span>TemporalObject<span style="color: #009900;">&#41;</span> object<span style="color: #009900;">&#41;</span>.<span style="color: #006633;">isGeldigOp</span><span style="color: #009900;">&#40;</span>peildatum<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
            <span style="color: #009900;">&#125;</span>
        <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> setActueleVersie<span style="color: #009900;">&#40;</span>TemporalObject actueleVersie<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>actueleVersie <span style="color: #339933;">==</span> <span style="color: #000066; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #000000; font-weight: bold;">throw</span> <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">IllegalArgumentException</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;actueleVersie is null&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
&nbsp;
        beeindigVorigeVersie<span style="color: #009900;">&#40;</span>actueleVersie<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">alleHistorischeVersies</span>.<span style="color: #006633;">add</span><span style="color: #009900;">&#40;</span>actueleVersie<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000066; font-weight: bold;">void</span> beeindigVorigeVersie<span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">final</span> TemporalObject actueleVersie<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        TemporalObject teBeeindigenVersie <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span>TemporalObject<span style="color: #009900;">&#41;</span> CollectionUtils.<span style="color: #006633;">find</span><span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">alleHistorischeVersies</span>, <span style="color: #000000; font-weight: bold;">new</span> Predicate<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">boolean</span> evaluate<span style="color: #009900;">&#40;</span><span style="color: #003399;">Object</span> object<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
                TemporalObject versie <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span>TemporalObject<span style="color: #009900;">&#41;</span> object<span style="color: #339933;">;</span>
                <span style="color: #000000; font-weight: bold;">return</span> versie.<span style="color: #006633;">isGeldigOp</span><span style="color: #009900;">&#40;</span>actueleVersie.<span style="color: #006633;">getIngangsdatum</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
            <span style="color: #009900;">&#125;</span>
        <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>teBeeindigenVersie <span style="color: #339933;">!=</span> <span style="color: #000066; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            teBeeindigenVersie.<span style="color: #006633;">beeindig</span><span style="color: #009900;">&#40;</span>actueleVersie.<span style="color: #006633;">getIngangsdatum</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> beeindig<span style="color: #009900;">&#40;</span><span style="color: #003399;">Date</span> einddatum<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        TemporalObject teBeeindigenVersie <span style="color: #339933;">=</span> getActueleVersie<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>teBeeindigenVersie <span style="color: #339933;">!=</span> <span style="color: #000066; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            teBeeindigenVersie.<span style="color: #006633;">beeindig</span><span style="color: #009900;">&#40;</span>einddatum<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

</p>
<p>Deze klasse wordt gebruikt om alle historische versies van een property bij te houden. Deze klasse kent methoden om de actuele versie op te vragen, om de versie die op een bepaalde datum geldig is op te vragen en om een nieuwe actuele versie toe te voegen of te beëindigen. Als er een nieuwe actuele versie wordt toegevoegd, wordt de op dat moment geldende versie beëindigd. Deze klasse is gebaseerd op de <a href="http://www.martinfowler.com/eaaDev/TemporalProperty.html">TemporalProperty Pattern</a> van Martin Fowler. </p>
<p><i><b>Let op:</b> Fowler noemt deze klasse <tt>TemporalCollection</tt>. Deze naam gebruik ik voor de lijst properties met historie, die ik in deel 4 zal behandelen. </i></p>
<h3>Voorbeeld</h3>
<p>Om de werking van bovenstaande klassen uit te leggen gebruiken we het voorbeeld uit deel 1. </p>
<p><i>Kees werkte vanaf 1-1-2003 op de afdeling Inkoop. Vanaf 1-1-2006 werkt hij op de afdeling Verkoop. Deze overgang werd op 1-2-2006 geregistreerd in het systeem.</i></p>
<p>We hebben hier te maken met de klassen <tt>Werknemer</tt> en <tt>Afdeling</tt>. Omdat de afdeling bij meerdere werknemers voor kan komen gebruiken we een <tt>AfdelingRelatie</tt> klasse om de geldigheid van een afdeling bij een werknemer te registreren.
<p>Het klasse model ziet er als volgt uit:<br />
<a href="http://blog.smart-java.nl/blog/wp-content/uploads/2008/12/classmodel-temporal-afdelingrelatie.png"><img src="http://blog.smart-java.nl/blog/wp-content/uploads/2008/12/classmodel-temporal-afdelingrelatie.png" alt="" title="klasse model werknemer-afdeling" width="500" height="127" class="aligncenter size-full wp-image-269" /></a>
</p>
<p><b>Werknemer</b></p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> Werknemer <span style="color: #009900;">&#123;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">private</span> TemporalProperty afdelingRelatie <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> TemporalProperty<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #003399;">String</span> naam<span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> Werknemer<span style="color: #009900;">&#40;</span><span style="color: #003399;">String</span> naam<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">super</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">naam</span> <span style="color: #339933;">=</span> naam<span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #003399;">String</span> getNaam<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">naam</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> setAfdeling<span style="color: #009900;">&#40;</span>Afdeling afdeling, <span style="color: #003399;">Date</span> ingangsdatum<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">afdelingRelatie</span>.<span style="color: #006633;">setActueleVersie</span><span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">new</span> AfdelingRelatie<span style="color: #009900;">&#40;</span>afdeling, ingangsdatum<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> Afdeling getAfdeling<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        AfdelingRelatie relatie <span style="color: #339933;">=</span> getAfdelingRelatie<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>relatie <span style="color: #339933;">!=</span> <span style="color: #000066; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #000000; font-weight: bold;">return</span> relatie.<span style="color: #006633;">getAfdeling</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
        <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #000066; font-weight: bold;">null</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> Afdeling getAfdeling<span style="color: #009900;">&#40;</span><span style="color: #003399;">Date</span> peildatum<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        AfdelingRelatie relatie <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span>AfdelingRelatie<span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">afdelingRelatie</span>.<span style="color: #006633;">getVersieOp</span><span style="color: #009900;">&#40;</span>peildatum<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>relatie <span style="color: #339933;">!=</span> <span style="color: #000066; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #000000; font-weight: bold;">return</span> relatie.<span style="color: #006633;">getAfdeling</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
        <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #000066; font-weight: bold;">null</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> AfdelingRelatie getAfdelingRelatie<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #009900;">&#40;</span>AfdelingRelatie<span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">afdelingRelatie</span>.<span style="color: #006633;">getActueleVersie</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> AfdelingRelatie getAfdelingRelatie<span style="color: #009900;">&#40;</span><span style="color: #003399;">Date</span> peildatum<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #009900;">&#40;</span>AfdelingRelatie<span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">afdelingRelatie</span>.<span style="color: #006633;">getVersieOp</span><span style="color: #009900;">&#40;</span>peildatum<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> uitDienst<span style="color: #009900;">&#40;</span><span style="color: #003399;">Date</span> datumUitdienst<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">afdelingRelatie</span>.<span style="color: #006633;">beeindig</span><span style="color: #009900;">&#40;</span>datumUitdienst<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

</p>
<p>De klasse <tt>Werknemer</tt> bevat een temporal property <tt>afdelingRelatie</tt> die alle historische versies van de afdelingen van de werknemer bevat. Verder bevat deze klasse de public methoden om de huidige afdeling op te vragen, de afdeling waar de werknemer werkte op een bepaalde datum op te vragen en om een nieuwe afdeling te koppelen aan de werknemer. Het opvragen en koppelen van de afdeling verloopt via de relatieklasse <tt>AfdelingRelatie</tt>, die de historie van een enkele versie bijhoudt. Als een werknemer uit dienst gaat, wordt de actuele versie van de relatie beëindigd.</p>
<p><b>AfdelingRelatie</b></p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> AfdelingRelatie <span style="color: #000000; font-weight: bold;">extends</span> TemporalObject <span style="color: #009900;">&#123;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">private</span> Afdeling afdeling<span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">protected</span> AfdelingRelatie<span style="color: #009900;">&#40;</span>Afdeling afdeling, <span style="color: #003399;">Date</span> ingangsdatum<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">super</span><span style="color: #009900;">&#40;</span>ingangsdatum<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">afdeling</span> <span style="color: #339933;">=</span> afdeling<span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> Afdeling getAfdeling<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">afdeling</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span></pre></div></div>

</p>
<p>De klasse <tt>AfdelingRelatie</tt> is afgeleid van de klasse TemporalObject omdat deze klasse de geldigheid bevat van de relatie tussen de werknemer en de afdeling. Omdat een temporal object <i>immutable</i> is, kan er alleen maar een nieuwe versie via de constructor worden aangemaakt met een ingangsdatum die de datum voorstelt waarop de werknemer op de nieuwe afdeling komt te werken.</p>
<p><b>Afdeling</b></p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> Afdeling <span style="color: #009900;">&#123;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #003399;">String</span> naam<span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> Afdeling<span style="color: #009900;">&#40;</span><span style="color: #003399;">String</span> naam<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">super</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">naam</span> <span style="color: #339933;">=</span> naam<span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #003399;">String</span> getNaam<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">naam</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

</p>
<p>De klasse <tt>Afdeling</tt> is een eenvoudige klasse die voor ons voorbeeld alleen de naam van de afdeling bevat.
<p>Het gebruik van de klassen en methoden volgt uit de volgende unit test.</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> testWerknemer<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		Werknemer werknemer <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Werknemer<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;Kees&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
		Afdeling afdeling <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Afdeling<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;Inkoop&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		werknemer.<span style="color: #006633;">setAfdeling</span><span style="color: #009900;">&#40;</span>afdeling, DateUtils.<span style="color: #006633;">maakDate</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">2003</span>, <span style="color: #cc66cc;">1</span>, <span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
		afdeling <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Afdeling<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;Verkoop&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		werknemer.<span style="color: #006633;">setAfdeling</span><span style="color: #009900;">&#40;</span>afdeling, DateUtils.<span style="color: #006633;">maakDate</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">2006</span>, <span style="color: #cc66cc;">1</span>, <span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
		assertEquals<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;Kees&quot;</span>, werknemer.<span style="color: #006633;">getNaam</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		assertEquals<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;Verkoop&quot;</span>, werknemer.<span style="color: #006633;">getAfdeling</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">getNaam</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		assertEquals<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;Verkoop&quot;</span>, werknemer.<span style="color: #006633;">getAfdeling</span><span style="color: #009900;">&#40;</span>DateUtils.<span style="color: #006633;">maakDate</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">2006</span>, <span style="color: #cc66cc;">1</span>, <span style="color: #cc66cc;">15</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">getNaam</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        	assertEquals<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;Inkoop&quot;</span>, werknemer.<span style="color: #006633;">getAfdeling</span><span style="color: #009900;">&#40;</span>DateUtils.<span style="color: #006633;">maakDate</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">2004</span>, <span style="color: #cc66cc;">1</span>, <span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">getNaam</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
		werknemer.<span style="color: #006633;">uitDienst</span><span style="color: #009900;">&#40;</span>DateUtils.<span style="color: #006633;">maakDate</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">2008</span>,<span style="color: #cc66cc;">1</span>,<span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        	assertNull<span style="color: #009900;">&#40;</span>werknemer.<span style="color: #006633;">getAfdeling</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #009900;">&#125;</span></pre></div></div>

<p><p>In deze test maken we een werknemer Kees aan, die begint te werken op de afdeling Inkoop op 1 januari 2003. Vanaf 1 januari 2006 werkt Kees op de afdeling Verkoop en vanaf  1 januari 2008 is Kees uit dienst.</p>
<h3>Hibernate mappings</h3>
<p>Tenslotte wil ik nog de Hibernate mappings voor de klassen <tt>Werknemer</tt> en <tt>AfdelingRelatie</tt> tonen om te laten zien hoe dit in zijn werk gaat.</p>
<p><b>Werknemer.hbm.xml</b></p>

<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;hibernate-mapping</span> <span style="color: #000066;">package</span>=<span style="color: #ff0000;">&quot;nl.ordina.temporal.example&quot;</span> <span style="color: #000066;">default-access</span>=<span style="color: #ff0000;">&quot;field&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
	<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;class</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;Werknemer&quot;</span> <span style="color: #000066;">table</span>=<span style="color: #ff0000;">&quot;Werknemer&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
&nbsp;
		... 
		<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;property</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;naam&quot;</span> <span style="color: #000066;">column</span>=<span style="color: #ff0000;">&quot;naam&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
&nbsp;
		<span style="color: #808080; font-style: italic;">&lt;!-- de verwijzing naar de afdelingrelatie --&gt;</span>
		<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;component</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;afdelingRelatie&quot;</span> </span>
<span style="color: #009900;">			<span style="color: #000066;">class</span>=<span style="color: #ff0000;">&quot;nl.ordina.temporal.singletemporal.TemporalProperty&quot;</span></span>
<span style="color: #009900;">			<span style="color: #000066;">lazy</span>=<span style="color: #ff0000;">&quot;false&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
			<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;bag</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;alleHistorischeVersies&quot;</span></span>
<span style="color: #009900;">				<span style="color: #000066;">cascade</span>=<span style="color: #ff0000;">&quot;all, delete-orphan&quot;</span> <span style="color: #000066;">lazy</span>=<span style="color: #ff0000;">&quot;false&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
				<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key</span> <span style="color: #000066;">column</span>=<span style="color: #ff0000;">&quot;werknemerId&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
				<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;one-to-many</span> <span style="color: #000066;">class</span>=<span style="color: #ff0000;">&quot;AfdelingRelatie&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
			<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/bag<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
		<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/component<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
&nbsp;
	<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/class<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/hibernate-mapping<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></div></div>

</p>
<p>De temporal property <tt>afdelingRelatie</tt> wordt als een component opgenomen in de mapping van <tt>Werknemer</tt>. Hierbinnen wordt de lijst <tt>alleHistorischeRelaties</tt> gemapt als een <tt>bag</tt>.</p>
<p><b>AfdelingRelatie.hbm.xml</b></p>

<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;hibernate-mapping</span> <span style="color: #000066;">package</span>=<span style="color: #ff0000;">&quot;nl.ordina.temporal.example&quot;</span> 	<span style="color: #000066;">default-access</span>=<span style="color: #ff0000;">&quot;field&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
	<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;class</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;AfdelingRelatie&quot;</span> <span style="color: #000066;">table</span>=<span style="color: #ff0000;">&quot;AfdelingRelatie&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
 		...
&nbsp;
		<span style="color: #808080; font-style: italic;">&lt;!-- temporale informatie --&gt;</span>
		<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;property</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;ingangsdatum&quot;</span> <span style="color: #000066;">type</span>=<span style="color: #ff0000;">&quot;date&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
		<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;property</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;einddatum&quot;</span> <span style="color: #000066;">type</span>=<span style="color: #ff0000;">&quot;date&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
&nbsp;
		<span style="color: #808080; font-style: italic;">&lt;!-- de verwijzing naar de afdeling --&gt;</span>
		<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;many-to-one</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;afdeling&quot;</span> <span style="color: #000066;">lazy</span>=<span style="color: #ff0000;">&quot;false&quot;</span> <span style="color: #000066;">class</span>=<span style="color: #ff0000;">&quot;Afdeling&quot;</span> <span style="color: #000066;">column</span>=<span style="color: #ff0000;">&quot;afdelingId&quot;</span> <span style="color: #000066;">cascade</span>=<span style="color: #ff0000;">&quot;none&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
	<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/class<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/hibernate-mapping<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></div></div>

</p>
<p>De mapping van de <tt>AfdelingRelatie</tt> bevat  de properties ingangsdatum en einddatum en een <tt>many-to-one</tt> relatie met de klasse <tt>Afdeling</tt>, die hier verder niet getoond wordt.</p>
<p>In het volgende deel zal het <tt>bitemporale pattern</tt> getoond worden. Hierbij zal het voorbeeld worden uitgebreid met registratiegegevens.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.smart-java.nl/blog/index.php/2008/12/07/temporale-data-%e2%80%93-deel-2-het-temporale-pattern/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
	</channel>
</rss>
