<?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/"
	xmlns:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>Dark Views &#187; Database</title>
	<atom:link href="http://blog.pdark.de/tag/database/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.pdark.de</link>
	<description>Opinions and views about computers, writing SciFi and everything else.</description>
	<lastBuildDate>Wed, 08 Feb 2012 06:43:18 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.com/</generator>
<cloud domain='blog.pdark.de' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://1.gravatar.com/blavatar/7741f06d762e6a53700b2915f21e3d77?s=96&#038;d=http%3A%2F%2Fs2.wp.com%2Fi%2Fbuttonw-com.png</url>
		<title>Dark Views &#187; Database</title>
		<link>http://blog.pdark.de</link>
	</image>
	<atom:link rel="search" type="application/opensearchdescription+xml" href="http://blog.pdark.de/osd.xml" title="Dark Views" />
	<atom:link rel='hub' href='http://blog.pdark.de/?pushpress=hub'/>
		<item>
		<title>What&#8217;s Wrong With XA/Two Phase Commit</title>
		<link>http://blog.pdark.de/2011/06/27/whats-wrong-with-xatwo-phase-commit/</link>
		<comments>http://blog.pdark.de/2011/06/27/whats-wrong-with-xatwo-phase-commit/#comments</comments>
		<pubDate>Mon, 27 Jun 2011 19:25:41 +0000</pubDate>
		<dc:creator>digulla</dc:creator>
				<category><![CDATA[Software]]></category>
		<category><![CDATA[Database]]></category>
		<category><![CDATA[Transactions]]></category>
		<category><![CDATA[Two Phase Commit]]></category>
		<category><![CDATA[XA]]></category>

		<guid isPermaLink="false">http://blog.pdark.de/?p=2086</guid>
		<description><![CDATA[To recap, two phase commit (XA) means that you have two or more systems which take part in a single transaction. The first phase ask all system &#8220;are you 100% sure that you can commit?&#8221; (prepare) and the second phase is the actual commit. Of course, the answer to the first question can be a lie. [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.pdark.de&amp;blog=6384723&amp;post=2086&amp;subd=darkviews&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>To recap, <a href="http://en.wikipedia.org/wiki/Two-phase_commit_protocol" target="_blank">two phase commit</a> (XA) means that you have two or more systems which take part in a single transaction. The first phase ask all system &#8220;are you 100% sure that you can commit?&#8221; (prepare) and the second phase is the actual commit.</p>
<p>Of course, the answer to the first question can be a lie. You can never be 100% sure that a commit will go through. The system might crash in the middle of the actual commit or the network my break between prepare and commit. Doom.</p>
<p>So XA doesn&#8217;t when it should. How can you solve this?</p>
<p>By using a less brittle protocol. Imagine you want to copy data from database A to B. You could use XA and clean up the mess every once in a while.</p>
<p>Or you could add a field to A which says &#8220;this has been copied to B&#8221; and when inserting data into B, you must ignore data that is already there. Here is the pseudo code:</p>
<ol>
<li>Create the connections</li>
<li>Find all rows in A that don&#8217;t have the flag set</li>
<li>Read all the rows and insert them into B. If a row already exists, skip it.</li>
<li>Set the flags for all copied rows in A.</li>
</ol>
<p>Note: You can&#8217;t use MAX(ID) or MAX(TIMESTAMP) here. Why not? Imagine:</p>
<div>
<ol>
<li>TX1 is created in A and a row is inserted. MAX(ID) == 2</li>
<li>TX2 is created in A and a row is inserted. MAX(ID) == 3! At this time, you can&#8217;t read WHERE ID == 2 but you can conclude from the gap in the ID values that it will soon exist.</li>
<li>TX2 is committed.</li>
<li>TX3 is created to copy the data to B. <strong>TX1 is still running! MAX(ID) == 3 but row 2 will not be copied!</strong></li>
<li>TX3 ends without row 2. Since MAX(ID) is now 3, it won&#8217;t ever be copied.</li>
</ol>
<p>If you&#8217;d rather avoid a &#8220;to copy&#8221; or &#8220;has been copied&#8221; flag in each row, create a &#8220;to transfer&#8221; table which contains IDs of the rows to copy. In step #4, delete the rows that have to be copied.</p>
<p>Advantages:</p>
<ol>
<li>Resilient. If the transfer fails in the middle for any reason, it can pick up where it left of. In the worst case, a lot of data will be copied again but data will never be lost. In the usual case, no data will be copied twice.</li>
<li>If you make a mistake, chances are that it won&#8217;t have matter much. Say you forget to set the &#8220;has been copied&#8221; flag. Well, for every transfer, too much data will be copied but it will still work. Slower than expected but <em>you won&#8217;t lose data</em>. The database will <em>always be consistent</em>!</li>
<li>Say something goes wrong in B and you need to transfer the data again. With my approach, you just reset the flags. It doesn&#8217;t matter if you can&#8217;t say for sure which flags to reset. If in doubt, reset all of them. The algorithm will heal itself.</li>
<li>You can copy the data in chunk sizes of your choice. It doesn&#8217;t matter if you copy everything in one go or in blocks of 1&#8217;000 rows or row by row.</li>
<li>It&#8217;s a simple algorithm, so it will be quick to implement and there is only a small chance for bugs. Even if there is a bug, in most cases, you will be able to resolve the situation with one or two simple SQL queries.</li>
</ol>
<p>Disadvantages:  The XA sales guy won&#8217;t make a buck from it. Expect some resistance.</p>
<p>&nbsp;</p>
</div>
<br /> Tagged: <a href='http://blog.pdark.de/tag/database/'>Database</a>, <a href='http://blog.pdark.de/tag/transactions/'>Transactions</a>, <a href='http://blog.pdark.de/tag/two-phase-commit/'>Two Phase Commit</a>, <a href='http://blog.pdark.de/tag/xa/'>XA</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/darkviews.wordpress.com/2086/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/darkviews.wordpress.com/2086/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/darkviews.wordpress.com/2086/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/darkviews.wordpress.com/2086/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/darkviews.wordpress.com/2086/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/darkviews.wordpress.com/2086/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/darkviews.wordpress.com/2086/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/darkviews.wordpress.com/2086/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/darkviews.wordpress.com/2086/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/darkviews.wordpress.com/2086/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/darkviews.wordpress.com/2086/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/darkviews.wordpress.com/2086/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/darkviews.wordpress.com/2086/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/darkviews.wordpress.com/2086/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.pdark.de&amp;blog=6384723&amp;post=2086&amp;subd=darkviews&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://blog.pdark.de/2011/06/27/whats-wrong-with-xatwo-phase-commit/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/8a4d6f03a8879432d8563aefbf48e787?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">digulla</media:title>
		</media:content>
	</item>
		<item>
		<title>Jazoon 2011, Day 2 &#8211; NoSQL &#8211; Schemaless Data-stores Not Only for the Cloud &#8211; Thomas Schank</title>
		<link>http://blog.pdark.de/2011/06/26/jazoon-2011-day-2-nosql-schemaless-data-stores-not-only-for-the-cloud-thomas-schank/</link>
		<comments>http://blog.pdark.de/2011/06/26/jazoon-2011-day-2-nosql-schemaless-data-stores-not-only-for-the-cloud-thomas-schank/#comments</comments>
		<pubDate>Sun, 26 Jun 2011 19:35:34 +0000</pubDate>
		<dc:creator>digulla</dc:creator>
				<category><![CDATA[Conference]]></category>
		<category><![CDATA[CoffeeScript]]></category>
		<category><![CDATA[Database]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Jazoon]]></category>
		<category><![CDATA[nosql]]></category>
		<category><![CDATA[SQL]]></category>

		<guid isPermaLink="false">http://blog.pdark.de/?p=2122</guid>
		<description><![CDATA[NoSQL &#8211; Schemaless Data-stores Not Only for the Cloud - Thomas Schank Thomas gave an overview of some NoSQL databases and the theoretical background of it. The main points are: SQL databases get inefficient as the data grows and if you need to split the data between instances (how do you join tables between two DB servers? [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.pdark.de&amp;blog=6384723&amp;post=2122&amp;subd=darkviews&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p><a href="http://jazoon.com/Conference/Wednesday-22-June/Thomas-Schank">NoSQL &#8211; Schemaless Data-stores Not Only for the Cloud</a> - Thomas Schank</p>
<p>Thomas gave an overview of some NoSQL databases and the theoretical background of it.</p>
<p>The main points are: SQL databases get inefficient as the data grows and if you need to split the data between instances (how do you join tables between two DB servers? Even if you can, performance is going to suffer).</p>
<p>But there are new problems: Data can be inconsistent for a while (keyword: <a title="Multiversion concurrency control" href="http://en.wikipedia.org/wiki/Multiversion_concurrency_control" target="_blank">MVCC</a>).</p>
<p><a title="on the other hand" href="http://en.wiktionary.org/wiki/OTOH" target="_blank">OTOH</a>, these databases don&#8217;t need locks and, as <a href="http://blog.rightscale.com/2011/04/25/amazon-ec2-outage-summary-and-lessons-learned/" target="_blank">Amazon demonstrated</a>, any kind of lock will eventually become a bottleneck:</p>
<blockquote><p><cite>Each node in a system should be able to <strong>make decisions purely based on local state</strong>. If you need to do something under high load with failures occurring and you need to reach agreement, you’re lost. <strong>If you’re concerned about scalability, any algorithm that forces you to run agreement will eventually become your bottleneck.</strong> Take that as a given.</cite></p>
<div>
<p>Werner Vogels, Amazon CTO and Vice President</p>
</div>
</blockquote>
<p>And since the servers can heal inconsistencies, broken connections don&#8217;t mean the end of the world. The acronym of the hour is BASE: Basically Available, Soft-state, Eventually consistent.</p>
<p>Interesting stuff, especially since every company owns a super-computer today. My own team has one with 64 cores, 64GB of RAM and 16TB of disk space sitting in 8 boxes spread under the desks of the developers. Not much but it only costs $8 000. And if we need more, we can simply buy another node. Unfortunately, it&#8217;s hard to leverage this power. I&#8217;ll come back to that in a later post.</p>
<p>One thing to take with you: If you can&#8217;t stand JavaScript but you need to write it, have a look at <a href="http://jashkenas.github.com/coffee-script/" target="_blank">CoffeeScript</a>.</p>
<p>Links:</p>
<ul>
<li><a href="http://dr.th.schank.ch/talks/2010/12/NoSQL" target="_blank">Slides</a></li>
<li>&#8220;<a href="http://blog.mudynamics.com/2010/04/01/why-nosql-is-bad-for-startups/" target="_blank">Why NoSQL is bad for startups</a>&#8221; (not completely serious, of course)</li>
</ul>
<br /> Tagged: <a href='http://blog.pdark.de/tag/coffeescript/'>CoffeeScript</a>, <a href='http://blog.pdark.de/tag/database/'>Database</a>, <a href='http://blog.pdark.de/tag/java/'>Java</a>, <a href='http://blog.pdark.de/tag/jazoon/'>Jazoon</a>, <a href='http://blog.pdark.de/tag/nosql/'>nosql</a>, <a href='http://blog.pdark.de/tag/sql/'>SQL</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/darkviews.wordpress.com/2122/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/darkviews.wordpress.com/2122/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/darkviews.wordpress.com/2122/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/darkviews.wordpress.com/2122/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/darkviews.wordpress.com/2122/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/darkviews.wordpress.com/2122/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/darkviews.wordpress.com/2122/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/darkviews.wordpress.com/2122/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/darkviews.wordpress.com/2122/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/darkviews.wordpress.com/2122/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/darkviews.wordpress.com/2122/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/darkviews.wordpress.com/2122/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/darkviews.wordpress.com/2122/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/darkviews.wordpress.com/2122/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.pdark.de&amp;blog=6384723&amp;post=2122&amp;subd=darkviews&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://blog.pdark.de/2011/06/26/jazoon-2011-day-2-nosql-schemaless-data-stores-not-only-for-the-cloud-thomas-schank/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/8a4d6f03a8879432d8563aefbf48e787?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">digulla</media:title>
		</media:content>
	</item>
		<item>
		<title>Declaring Relations Between Model Instances</title>
		<link>http://blog.pdark.de/2011/03/14/declaring-relations-between-model-instances/</link>
		<comments>http://blog.pdark.de/2011/03/14/declaring-relations-between-model-instances/#comments</comments>
		<pubDate>Mon, 14 Mar 2011 08:43:36 +0000</pubDate>
		<dc:creator>digulla</dc:creator>
				<category><![CDATA[Software]]></category>
		<category><![CDATA[Database]]></category>
		<category><![CDATA[Intentional programming]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[ManyToMany]]></category>
		<category><![CDATA[Modeling]]></category>
		<category><![CDATA[OneToMany]]></category>
		<category><![CDATA[OneToOne]]></category>
		<category><![CDATA[ParentChild]]></category>
		<category><![CDATA[Persistence]]></category>

		<guid isPermaLink="false">http://blog.pdark.de/?p=1805</guid>
		<description><![CDATA[I&#8217;ve been playing with Xtext 1.0 the last three weeks. The editor support is most impressive. It&#8217;s one of those well balanced technologies that work &#8220;right&#8221; out of the box, offer lots of places where to hook in to tweak things. The last few days, I&#8217;ve been chewing on a hard problem: Relations. I could [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.pdark.de&amp;blog=6384723&amp;post=1805&amp;subd=darkviews&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been playing with <a href="http://www.eclipse.org/Xtext/">Xtext 1.0</a> the last three weeks. The editor support is most impressive. It&#8217;s one of those well balanced technologies that work &#8220;right&#8221; out of the box, offer lots of places where to hook in to tweak things.</p>
<p>The last few days, I&#8217;ve been chewing on a hard problem: Relations. I could to this:</p>
<p><pre class="brush: java;">
class A {
}

class B {
    A parent 1:*;
}
</pre></p>
<p>Read: Instances of B have a field &#8220;parent&#8221; that references instances of A. There is a list in A with all instances of B where the field &#8220;parent&#8221; is that exact instance. In simple words, it&#8217;s a parent-child relation between A and B. For each B, there is always one A. Each A can have several B&#8217;s attached.</p>
<p>Or like this:</p>
<p><pre class="brush: java;">
class A {
}

class B {
}

relation A children 1:* B parent;
</pre></p>
<p>The first solution avoids repetition but when looking at A, you will miss the fact that it has fields. It looks empty but the declaration in B adds a field. I don&#8217;t like it. While it might work in this case, how do you map <a href="http://en.wikibooks.org/wiki/Java_Persistence/ManyToMany">N:M</a>? Where do you declare a <a href="http://en.wikibooks.org/wiki/Java_Persistence/ManyToMany">many-to-many relation</a>? In A or in B? My guts say: Don&#8217;t do it.</p>
<p>The second solution is also flawed if less so. Here, both classes are empty. I have to look up the relations to see what else is going on. And I have to repeat information. I don&#8217;t like it.</p>
<p>Time to take a step back and sleep over it.</p>
<p>Fast forward over the weekend.</p>
<p>How about this:</p>
<p><pre class="brush: java;">
class A {
}
parent of
class B {
}
</pre></p>
<p>One word: Intent. A construct in a programming language should clearly communicate <strong>intent</strong>. Which is one of the weak points in Java: It&#8217;s hard to express what you intend with Java. It&#8217;s not impossible but it takes years of experience to avoid the luring shortcuts.</p>
<p>So this new syntax clearly states what I want: A&#8217;s are parents of B&#8217;s. No repetition. No odd &#8220;1:*&#8221; which every reader has to decode. Which you can get wrong.</p>
<p>But what if A is parent of more classes? Simple:</p>
<p><pre class="brush: java;">
class A { }
parent of {
    class B { } parent of class X { }
    class C { }
    ...
}
</pre></p>
<p>See? It nests. Let&#8217;s add tree-like structures to the mix:</p>
<p><pre class="brush: java;">
tree class A { }
parent of {
    class B { } parent of class X { }
    class C { }
    ...
}
</pre></p>
<p>So A gets a parent-child relation with itself. One word says everything: <a href="http://en.wikibooks.org/wiki/Java_Persistence/OneToMany">Ownership</a>. <a href="http://en.wikipedia.org/wiki/Cardinality_(data_modeling)">Cardinality</a>. Field names.</p>
<p>My gut likes it. Listen to your guts. Especially when a simple solution tries to lure you into a shortcut.</p>
<br /> Tagged: <a href='http://blog.pdark.de/tag/database/'>Database</a>, <a href='http://blog.pdark.de/tag/intentional-programming/'>Intentional programming</a>, <a href='http://blog.pdark.de/tag/java/'>Java</a>, <a href='http://blog.pdark.de/tag/manytomany/'>ManyToMany</a>, <a href='http://blog.pdark.de/tag/modeling/'>Modeling</a>, <a href='http://blog.pdark.de/tag/onetomany/'>OneToMany</a>, <a href='http://blog.pdark.de/tag/onetoone/'>OneToOne</a>, <a href='http://blog.pdark.de/tag/parentchild/'>ParentChild</a>, <a href='http://blog.pdark.de/tag/persistence/'>Persistence</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/darkviews.wordpress.com/1805/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/darkviews.wordpress.com/1805/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/darkviews.wordpress.com/1805/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/darkviews.wordpress.com/1805/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/darkviews.wordpress.com/1805/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/darkviews.wordpress.com/1805/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/darkviews.wordpress.com/1805/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/darkviews.wordpress.com/1805/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/darkviews.wordpress.com/1805/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/darkviews.wordpress.com/1805/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/darkviews.wordpress.com/1805/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/darkviews.wordpress.com/1805/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/darkviews.wordpress.com/1805/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/darkviews.wordpress.com/1805/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.pdark.de&amp;blog=6384723&amp;post=1805&amp;subd=darkviews&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://blog.pdark.de/2011/03/14/declaring-relations-between-model-instances/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/8a4d6f03a8879432d8563aefbf48e787?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">digulla</media:title>
		</media:content>
	</item>
		<item>
		<title>TNBT: Persistence</title>
		<link>http://blog.pdark.de/2011/02/19/tnbt-persistence/</link>
		<comments>http://blog.pdark.de/2011/02/19/tnbt-persistence/#comments</comments>
		<pubDate>Sat, 19 Feb 2011 20:20:50 +0000</pubDate>
		<dc:creator>digulla</dc:creator>
				<category><![CDATA[Software]]></category>
		<category><![CDATA[Data]]></category>
		<category><![CDATA[Data Warehousing]]></category>
		<category><![CDATA[Database]]></category>
		<category><![CDATA[Databases]]></category>
		<category><![CDATA[Persistence]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[TNBT]]></category>
		<category><![CDATA[XML]]></category>

		<guid isPermaLink="false">http://blog.pdark.de/?p=1723</guid>
		<description><![CDATA[In this issue of &#8220;The Next Big Thing&#8221;, I&#8217;ll talk about something that every software uses and which is always developed again from scratch for every application: Persistence. Every application needs to load data from &#8220;somewhere&#8221; (user preferences, config settings, data to process) and after processing the data, it needs to save the results. Persistence [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.pdark.de&amp;blog=6384723&amp;post=1723&amp;subd=darkviews&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>In this issue of &#8220;The Next Big Thing&#8221;, I&#8217;ll talk about something that every software uses and which is always developed again from scratch for every application: Persistence.</p>
<p>Every application needs to load data from &#8220;somewhere&#8221; (user preferences, config settings, data to process) and after processing the data, it needs to save the results. Persistence is the most important feature of any software. Without it, the code would be useless.</p>
<p>Oddly, the most important area of the software isn&#8217;t a shiny skyscraper but a swamp: Muddy, boggy, suffocating.</p>
<p>Therefore, the next big thing in software development must make loading and saving data a bliss. Some features it needs to have:</p>
<ul>
<li>Transaction contexts to define which data needs to be rolled back in case of an error. Changes to the data model must be atomic by default. Even if I add 5,000 elements at once, either all or none of them must be added when an error happens.</li>
<li>Persistence must be transparent. The language should support rules how to transform data for a specific storage (file, database) but these should be generic. I don&#8217;t want to poison my data model with thousands of annotations.</li>
<li>All types must support persistence by default; not being able to be persisted must be the exception.</li>
<li>Creating a binary file format must be as simple as defining the XML format.</li>
<li>It must have optimizers (which run in the background like garbage collection runs today) that determine how much of the model graph needs to be loaded from a storage.</li>
</ul>
<p>&#8220;The Next Big Thing&#8221; is a series of blog posts in which I dream about features of a programming language which will replace OO just like OO replaced structured programming.</p>
<br /> Tagged: <a href='http://blog.pdark.de/tag/data/'>Data</a>, <a href='http://blog.pdark.de/tag/data-warehousing/'>Data Warehousing</a>, <a href='http://blog.pdark.de/tag/database/'>Database</a>, <a href='http://blog.pdark.de/tag/databases/'>Databases</a>, <a href='http://blog.pdark.de/tag/persistence/'>Persistence</a>, <a href='http://blog.pdark.de/tag/programming/'>Programming</a>, <a href='http://blog.pdark.de/tag/tnbt/'>TNBT</a>, <a href='http://blog.pdark.de/tag/xml/'>XML</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/darkviews.wordpress.com/1723/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/darkviews.wordpress.com/1723/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/darkviews.wordpress.com/1723/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/darkviews.wordpress.com/1723/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/darkviews.wordpress.com/1723/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/darkviews.wordpress.com/1723/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/darkviews.wordpress.com/1723/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/darkviews.wordpress.com/1723/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/darkviews.wordpress.com/1723/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/darkviews.wordpress.com/1723/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/darkviews.wordpress.com/1723/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/darkviews.wordpress.com/1723/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/darkviews.wordpress.com/1723/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/darkviews.wordpress.com/1723/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.pdark.de&amp;blog=6384723&amp;post=1723&amp;subd=darkviews&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://blog.pdark.de/2011/02/19/tnbt-persistence/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/8a4d6f03a8879432d8563aefbf48e787?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">digulla</media:title>
		</media:content>
	</item>
		<item>
		<title>ORA-01461: can bind a LONG value only for insert into a LONG column tips</title>
		<link>http://blog.pdark.de/2010/08/23/ora-01461-can-bind-a-long-value-only-for-insert-into-a-long-column-tips/</link>
		<comments>http://blog.pdark.de/2010/08/23/ora-01461-can-bind-a-long-value-only-for-insert-into-a-long-column-tips/#comments</comments>
		<pubDate>Mon, 23 Aug 2010 15:19:40 +0000</pubDate>
		<dc:creator>digulla</dc:creator>
				<category><![CDATA[Software]]></category>
		<category><![CDATA[Database]]></category>
		<category><![CDATA[Error message]]></category>
		<category><![CDATA[ORA-01461]]></category>
		<category><![CDATA[Oracle]]></category>

		<guid isPermaLink="false">http://blog.pdark.de/?p=1122</guid>
		<description><![CDATA[Should you ever encounter this message: ORA-01461: can bind a LONG value only for insert into a LONG column tips then chances are you tried to insert more than 4096 characters at once. Again the price for useless error messages goes to &#8230; Oracle! To add insult to injury, I couldn&#8217;t find anything useful related [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.pdark.de&amp;blog=6384723&amp;post=1122&amp;subd=darkviews&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Should you ever encounter this message:</p>
<blockquote><p>ORA-01461: can bind a LONG value only for insert into a LONG column tips</p></blockquote>
<p>then chances are you tried to insert more than 4096 characters at once.</p>
<p>Again the price for useless error messages goes to &#8230; Oracle! <img src='http://s1.wp.com/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> </p>
<p>To add insult to injury, I couldn&#8217;t find anything useful related to this error with Oracle&#8217;s own site search.</p>
<br /> Tagged: <a href='http://blog.pdark.de/tag/database/'>Database</a>, <a href='http://blog.pdark.de/tag/error-message/'>Error message</a>, <a href='http://blog.pdark.de/tag/ora-01461/'>ORA-01461</a>, <a href='http://blog.pdark.de/tag/oracle/'>Oracle</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/darkviews.wordpress.com/1122/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/darkviews.wordpress.com/1122/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/darkviews.wordpress.com/1122/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/darkviews.wordpress.com/1122/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/darkviews.wordpress.com/1122/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/darkviews.wordpress.com/1122/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/darkviews.wordpress.com/1122/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/darkviews.wordpress.com/1122/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/darkviews.wordpress.com/1122/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/darkviews.wordpress.com/1122/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/darkviews.wordpress.com/1122/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/darkviews.wordpress.com/1122/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/darkviews.wordpress.com/1122/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/darkviews.wordpress.com/1122/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.pdark.de&amp;blog=6384723&amp;post=1122&amp;subd=darkviews&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://blog.pdark.de/2010/08/23/ora-01461-can-bind-a-long-value-only-for-insert-into-a-long-column-tips/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/8a4d6f03a8879432d8563aefbf48e787?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">digulla</media:title>
		</media:content>
	</item>
		<item>
		<title>Testing the Impossible: Shifting IDs</title>
		<link>http://blog.pdark.de/2009/10/07/testing-the-impossible-shifting-ids/</link>
		<comments>http://blog.pdark.de/2009/10/07/testing-the-impossible-shifting-ids/#comments</comments>
		<pubDate>Wed, 07 Oct 2009 08:38:17 +0000</pubDate>
		<dc:creator>digulla</dc:creator>
				<category><![CDATA[Software]]></category>
		<category><![CDATA[Database]]></category>
		<category><![CDATA[Hibernate]]></category>
		<category><![CDATA[ID]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Spring]]></category>
		<category><![CDATA[Testing]]></category>

		<guid isPermaLink="false">http://blog.pdark.de/?p=705</guid>
		<description><![CDATA[So you couldn&#8217;t resist and wrote tests against the database. With Hibernate, no less. And maybe some Spring. And to make things more simple, toString() contains the IDs of the objects in the database. Now, you want to check the results of queries and other operations using my advice how to verify several values at [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.pdark.de&amp;blog=6384723&amp;post=705&amp;subd=darkviews&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>So you couldn&#8217;t resist and wrote tests against the database. With Hibernate, no less. And maybe some Spring. And to make things more simple, <code>toString()</code> contains the IDs of the objects in the database. Now, you want to check the results of queries and other operations using my advice <a href="http://blog.pdark.de/2009/03/23/testing-the-impossible-asserting-several-values/">how to verify several values at once</a>.</p>
<p>During your first run, your DB returns some values, you copy them into a String. When you run the tests again, the tests fail because all the IDs have changed. Bummer. Now what? Just verify that the correct number of results was returned?</p>
<p>Don&#8217;t. <code>assertEquals (3, list.size())</code> doesn&#8217;t give you a clue where to search for the error when the assert fails.</p>
<p>The solution is to give each ID a name. The name always stays the same and when you look at the test results, you&#8217;ll immediately know that the ID has been &#8220;fixated&#8221; (unlike when you&#8217;d replace the number with another, for example). Here is the code:</p>
<p><pre class="brush: java;">
import java.util.*;

/** Helper class to fixate changing object IDs */
public class IDFixer
{
    private Map&lt;String, String&gt; replacements = new HashMap&lt;String, String&gt; ();
    private Map&lt;String, Exception&gt; usedNames = new HashMap&lt;String, Exception&gt; ();
    
    /** Assign a name to the number which follows the string &lt;code&gt;id=&lt;/code&gt; in the object's
     * &lt;code&gt;toString()&lt;/code&gt; method. */
    public void register (Object o, String name)
    {
        if (o == null)
            return;
        
        String s = o.toString ();
        int pos = s.indexOf (&quot;id=&quot;);
        if (pos != -1)
            pos = s.indexOf (',', pos);
        if (pos == -1)
            throw new RuntimeException (&quot;Can't find 'id=' in &quot; + s);
        String search = s.substring (0, pos + 1);
        
        pos = search.lastIndexOf ('=');
        String replace = search.substring (0, pos + 1) + name + &quot;,&quot;;
        
        add (name, search, replace);
        
        registerSpecial (o, name);
    }

    /** Add a search&amp;replace pattern. */
    protected void add (String name, String search, String replace)
    {
        if (usedNames.containsKey (replace))
            throw new RuntimeException (&quot;Name &quot;+name+&quot; is already in use&quot;, usedNames.get (replace));
        
        //System.out.println (&quot;+++ [&quot;+search+&quot;] -&gt; [&quot;+replace+&quot;]&quot;);
        usedNames.put (replace, new Exception (&quot;Name was registered here&quot;));
        replacements.put (search, replace);
    }
    
    /** Allow for special mappings */
    protected void registerSpecial (Object o, String name)
    {
        // NOP
    }

    /** Turn a &lt;code&gt;Collection&lt;/code&gt; into a &lt;code&gt;String&lt;/code&gt;, replacing all IDs with names. */
    public String toString (Collection c)
    {
        StringBuilder buffer = new StringBuilder (10240);
        String delim = &quot;&quot;;
        for (Object o: c)
        {
            buffer.append (delim);
            delim = &quot;\n&quot;;
            buffer.append (o);
        }
        return toString (buffer);
    }
    
    /** Turn a &lt;code&gt;Map&lt;/code&gt; into a &lt;code&gt;String&lt;/code&gt;, replacing all IDs with names. */
    public String toString (Map m)
    {
        StringBuilder buffer = new StringBuilder (10240);
        String delim = &quot;&quot;;
        for (Iterator iter=m.entrySet ().iterator (); iter.hasNext (); )
        {
            Map.Entry e = (Map.Entry)iter.next ();
            
            buffer.append (delim);
            delim = &quot;\n&quot;;
            buffer.append (e.getKey ());
            buffer.append ('=');
            buffer.append (e.getValue ());
        }
        return toString (buffer);
    }
    
    /** Turn an &lt;code&gt;Object&lt;/code&gt; to a &lt;code&gt;String&lt;/code&gt;, replacing all IDs with names.
     * 
     *  &lt;p&gt;If the object is a &lt;code&gt;Collection&lt;/code&gt; or a &lt;code&gt;Map&lt;/code&gt;, the special collection handling methods will be called. */
    public String toString (Object o)
    {
        if (o instanceof Collection)
        {
            return toString ((Collection)o);
        }
        else if (o instanceof Map)
        {
            return toString ((Map)o);
        }
        
        if (o == null)
            return &quot;null&quot;;

        String s = o.toString ();
        for (Map.Entry&lt;String, String&gt; entry: replacements.entrySet ())
        {
            s = s.replace (entry.getKey (), entry.getValue ());
        }
        
        return s;
    }

    public boolean knowsAbout (String key)
    {
        return replacements.containsKey (key);
    }
}
</pre></p>
<p>To use the <code>IDFixer</code>, call <code>register(object, name)</code> to assign a name to whatever follows the number after <code>id=</code>. The method will search for this substring in the result of calling <code>object.toString()</code>.</p>
<p>If you call <code>IDFixer.toString(object)</code> for a single object or a collection, it will replace <code>id=number</code> with <code>id=name</code> everywhere. If you have references between objects, you can register additional pattern to be replaced by overriding <code>registerSpecial()</code>.</p>
<p>To make it easier to compare lists and maps in <code>assertEquals()</code>, each item gets its own line.</p>
<br /> Tagged: Database, Hibernate, ID, Java, Spring, Testing <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/darkviews.wordpress.com/705/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/darkviews.wordpress.com/705/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/darkviews.wordpress.com/705/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/darkviews.wordpress.com/705/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/darkviews.wordpress.com/705/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/darkviews.wordpress.com/705/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/darkviews.wordpress.com/705/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/darkviews.wordpress.com/705/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/darkviews.wordpress.com/705/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/darkviews.wordpress.com/705/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/darkviews.wordpress.com/705/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/darkviews.wordpress.com/705/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/darkviews.wordpress.com/705/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/darkviews.wordpress.com/705/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.pdark.de&amp;blog=6384723&amp;post=705&amp;subd=darkviews&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://blog.pdark.de/2009/10/07/testing-the-impossible-shifting-ids/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/8a4d6f03a8879432d8563aefbf48e787?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">digulla</media:title>
		</media:content>
	</item>
		<item>
		<title>Traits for Groovy/Java</title>
		<link>http://blog.pdark.de/2009/06/25/traits-for-groovyjava/</link>
		<comments>http://blog.pdark.de/2009/06/25/traits-for-groovyjava/#comments</comments>
		<pubDate>Thu, 25 Jun 2009 18:29:28 +0000</pubDate>
		<dc:creator>digulla</dc:creator>
				<category><![CDATA[Software]]></category>
		<category><![CDATA[Database]]></category>
		<category><![CDATA[Groovy]]></category>
		<category><![CDATA[Hibernate]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[JPA]]></category>
		<category><![CDATA[Sensei]]></category>
		<category><![CDATA[Swing]]></category>
		<category><![CDATA[SWT]]></category>

		<guid isPermaLink="false">http://blog.pdark.de/?p=641</guid>
		<description><![CDATA[I&#8217;m again toying with the idea of traits for Java (or rather Groovy). Just to give you a rough idea if you haven&#8217;t heard about this before, think of my Sensei application template: A most simple model but it contains everything you can encounter in an application: Parent-child/tree structure, 1:N and N:M mappings. Now the [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.pdark.de&amp;blog=6384723&amp;post=641&amp;subd=darkviews&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m again toying with the idea of traits for Java (or rather <a href="http://groovy.codehaus.org/">Groovy</a>). Just to give you a rough idea if you haven&#8217;t heard about this before, think of my <a href="http://blog.pdark.de/2007/07/11/whats-wrong-with-java-part-1/">Sensei application template</a>:</p>
<p><pre class="brush: java;">
class Knowledge {
    Set tags;
    Knowledge parent;
    List children;
    String name;
    String content;
}
class Tag { String name; }
class Relation { String name; Knowledge from, to;
</pre></p>
<p>A most simple model but it contains everything you can encounter in an application: Parent-child/tree structure, 1:N and N:M mappings. Now the idea is to have a way to build a UI and a DB mapping from this code. The idea of traits is to implement real properties in Java.</p>
<p>So instead of fields with primitive types, you have real objects to work with:</p>
<p><pre class="brush: java;">
    assert &quot;name&quot; == Knowledge.name.getName()
</pre></p>
<p>These objects exist partially at the class and at the instance level. There is static information at the class level (the name of the property) and there is instance information (the current value). But it should be possible to add more information at both levels. So a DB mapper can add necessary translation information to the class level and a Hibernate mapper can build on top of that.</p>
<p>Oh, I hear you cry &#8220;annotations!&#8221; But annotations can suck, too. You can&#8217;t have smart defaults with annotations. For example, you can&#8217;t say &#8220;I want all fields called &#8216;timestamp&#8217; to be mapped with an <code>java.sql.Timestamp</code>&#8220;. You have to add the annotation to each timestamp field. That violates DRY. It quickly gets really bad when you have to do this for several mappers: Database, <a href="https://www.hibernate.org/">Hibernate</a>, <a href="http://java.sun.com/javaee/overview/faq/persistence.jsp">JPA</a>, the UI, Swing, <a href="http://www.eclipse.org/swt/">SWT</a>, <a href="http://code.google.com/intl/de-DE/webtoolkit/">GWT</a>. Suddenly, each property would need 10+ annotations!</p>
<p>I think I&#8217;ve found a solution which should need relatively few lines of code with Groovy. I&#8217;ll let that stew for a couple of days in by subconscious and post another article when it&#8217;s well done <img src='http://s0.wp.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<br /> Tagged: Database, Groovy, Hibernate, Java, JPA, Sensei, Swing, SWT <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/darkviews.wordpress.com/641/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/darkviews.wordpress.com/641/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/darkviews.wordpress.com/641/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/darkviews.wordpress.com/641/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/darkviews.wordpress.com/641/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/darkviews.wordpress.com/641/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/darkviews.wordpress.com/641/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/darkviews.wordpress.com/641/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/darkviews.wordpress.com/641/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/darkviews.wordpress.com/641/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/darkviews.wordpress.com/641/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/darkviews.wordpress.com/641/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/darkviews.wordpress.com/641/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/darkviews.wordpress.com/641/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.pdark.de&amp;blog=6384723&amp;post=641&amp;subd=darkviews&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://blog.pdark.de/2009/06/25/traits-for-groovyjava/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/8a4d6f03a8879432d8563aefbf48e787?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">digulla</media:title>
		</media:content>
	</item>
		<item>
		<title>Jazoon, Day 2: XWiki</title>
		<link>http://blog.pdark.de/2009/06/24/jazoon-day-2-xwiki/</link>
		<comments>http://blog.pdark.de/2009/06/24/jazoon-day-2-xwiki/#comments</comments>
		<pubDate>Wed, 24 Jun 2009 12:18:40 +0000</pubDate>
		<dc:creator>digulla</dc:creator>
				<category><![CDATA[Conference]]></category>
		<category><![CDATA[Software]]></category>
		<category><![CDATA[Database]]></category>
		<category><![CDATA[Groovy]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Jazoon]]></category>
		<category><![CDATA[MediaWiki]]></category>
		<category><![CDATA[MoinMoin]]></category>
		<category><![CDATA[Velocity]]></category>
		<category><![CDATA[wiki]]></category>
		<category><![CDATA[XWiki]]></category>

		<guid isPermaLink="false">http://blog.pdark.de/?p=638</guid>
		<description><![CDATA[I&#8217;m a huge fan of wikis. Not necessarily MediaWiki (holy ugly, Batman, the syntax!). I dig MoinMoin. I just heard the talk by Vincent Massol about next generation wikis. Okay, I can hear you moan under the load of buzzwords but give me a moment. XWiki looks really promising. Wikis basically allow to publish mostly [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.pdark.de&amp;blog=6384723&amp;post=638&amp;subd=darkviews&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m a huge fan of wikis. Not necessarily MediaWiki (holy ugly, Batman, the syntax!). I dig <a href="http://moinmo.in/">MoinMoin</a>. I just heard <a href="http://jazoon.com/en/conference/presentationdetails.html?type=sid&amp;detail=7400">the talk</a> by <a href="http://jazoon.com/en/conference/authors/Vincent_Massol">Vincent Massol</a> about next generation wikis. Okay, I can hear you moan under the load of buzzwords but give me a moment. <a href="http://www.xwiki.org/">XWiki</a> looks really promising.</p>
<p>Wikis basically allow to publish mostly unstructured data. I say &#8220;mostly&#8221; because wikis give them some structure but not (too) much: You can organize it in pages and put it into context (by linking between the pages). Often, this is enough. But recently, MediaWiki has started to add support for structured data. See that <a href="http://en.wikipedia.org/wiki/68000">infobox in the top left corner</a>? But that&#8217;s just half-hearted.</p>
<p>XWiki takes this one step further. XWiki, as I understand it, is a framework of loosely coupled components which allow you to create a wiki. The default one is pretty good, too, so most of the time, you won&#8217;t even get into this. The cool part about XWiki is that you can define a class <strong>inside of it</strong>. Let me repeat: You can create a page (like a normal text page) that XWiki will treat as a class definition. So this class gets versioned, etc. You can then add attributes as you like.</p>
<p>After that, you can create instances of this class. The instances are again wiki pages. You can even use more than a single instance on a page, for example, you can have several tag instances and a single person instance. Instances are versioned, too. Of course they are, this is a wiki!</p>
<p>Now you need to display that data. You can use <a href="http://velocity.apache.org/">Velocity</a> or <a href="http://groovy.codehaus.org/">Groovy</a> for that. And guess what, the view is &#8230; a wiki page. So your designers can create a beautiful look for your the boring raw data. With versions and comments and everything. While some other guys are adding data to the system.</p>
<p>In &#8220;normal&#8221; wiki pages, you can reference these instances and render them using such a template. The same is true for editors. With a few lines of code, you can create overview pages: All instances of a class or all instances with or without a certain property or you can use Groovy to do whatever you can think of.</p>
<p>Now imagine this: You have an existing database where your marketing guys can, say, plan the next campaign. They can use all the wiki features to collect ideas, filter and verify them, to come up with a really good plan. Some of that data needs to go into a corporate database. In former wikis, you&#8217;d have to use an external application, switch back and forth, curse a lot when they get out of sync.</p>
<p>With XWiki, you can finally annotate data in your corporate database with a wiki page, with all the power of a wiki and you can even <strong>display the data set in the wiki and edit it there</strong>. Granted, the data set won&#8217;t be versioned unless your corporate database allows that but it&#8217;s simple to do the versioning in the data access layer (for example, you can save all modifications in a log database).</p>
<p>Suddenly, possibilities open up.</p>
<br /> Tagged: Database, Groovy, Java, Jazoon, MediaWiki, MoinMoin, Velocity, wiki, XWiki <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/darkviews.wordpress.com/638/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/darkviews.wordpress.com/638/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/darkviews.wordpress.com/638/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/darkviews.wordpress.com/638/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/darkviews.wordpress.com/638/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/darkviews.wordpress.com/638/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/darkviews.wordpress.com/638/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/darkviews.wordpress.com/638/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/darkviews.wordpress.com/638/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/darkviews.wordpress.com/638/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/darkviews.wordpress.com/638/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/darkviews.wordpress.com/638/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/darkviews.wordpress.com/638/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/darkviews.wordpress.com/638/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.pdark.de&amp;blog=6384723&amp;post=638&amp;subd=darkviews&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://blog.pdark.de/2009/06/24/jazoon-day-2-xwiki/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/8a4d6f03a8879432d8563aefbf48e787?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">digulla</media:title>
		</media:content>
	</item>
		<item>
		<title>Testing The Impossible: Inserting Into Database</title>
		<link>http://blog.pdark.de/2009/06/05/testing-the-impossible-inserting-into-database/</link>
		<comments>http://blog.pdark.de/2009/06/05/testing-the-impossible-inserting-into-database/#comments</comments>
		<pubDate>Fri, 05 Jun 2009 18:34:23 +0000</pubDate>
		<dc:creator>digulla</dc:creator>
				<category><![CDATA[Software]]></category>
		<category><![CDATA[Database]]></category>
		<category><![CDATA[JUnit]]></category>
		<category><![CDATA[TDD]]></category>
		<category><![CDATA[Testing]]></category>

		<guid isPermaLink="false">http://blog.pdark.de/?p=626</guid>
		<description><![CDATA[Tests run slow when you need a database. An in-memory database like HSQLDB or Derby helps but at a cost: Your real database will accept some SQL which your test database won&#8217;t. So the question is: How can you write a performant test which uses the SQL of the real database? My solution is to [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.pdark.de&amp;blog=6384723&amp;post=626&amp;subd=darkviews&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Tests run slow when you need a database. An in-memory database like <a href="http://hsqldb.org/">HSQLDB</a> or <a href="http://db.apache.org/derby/">Derby</a> helps but at a cost: Your real database will accept some SQL which your test database won&#8217;t. So the question is: How can you write a performant test which uses the SQL of the real database?</p>
<p>My solution is to wrap the JDBC layer. Either use a mock JDBC interface like the one provided by <a href="http://mockrunner.sourceforge.net/">mockrunner</a>. Or write your own. With Java 5 and varargs, this is simple:</p>
<p><pre class="brush: java;">
public int update (Connection conn, String sql, Object... params) throws SQLException {
    PreparedStatement stmt = null;
    try {
        stmt = conn.prepareStatement (sql);
        int i = 1;
        for (Object p: params) {
            stmt.setObject(i++, p);
        }
        return stmt.executeUpdate ();
    }
    finally {
        stmt.close ();
    }
}
</pre></p>
<p>Put all these methods into an object that you can pass around. In your tests, override this object with a mockup that simply collects the SQL strings and parameter arrays. You can even mix and match: By examining the SQL string, you can decide whether you want to run a query against the database or handle it internally.</p>
<p>This way, you can collect any newly created objects but still load some background data from the database (until you get bored and make the query methods return predefined results).</p>
<p>In the asserts, just collect all the results into a big String and <a href="http://blog.pdark.de/2009/03/23/testing-the-impossible-asserting-several-values/">compare them all at once</a>.</p>
<p>Notes: The code above is a bit more complicated if you allow <tt>null</tt> values. In this case, you need to tell JDBC what the column type is. My solution is a <tt>NullParameter</tt> class which contains the type. If the loop encounters this class, then it calls <tt>setNull()</tt> instead of <tt>setObject()</tt>.</p>
<br /> Tagged: Database, JUnit, TDD, Testing <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/darkviews.wordpress.com/626/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/darkviews.wordpress.com/626/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/darkviews.wordpress.com/626/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/darkviews.wordpress.com/626/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/darkviews.wordpress.com/626/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/darkviews.wordpress.com/626/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/darkviews.wordpress.com/626/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/darkviews.wordpress.com/626/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/darkviews.wordpress.com/626/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/darkviews.wordpress.com/626/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/darkviews.wordpress.com/626/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/darkviews.wordpress.com/626/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/darkviews.wordpress.com/626/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/darkviews.wordpress.com/626/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.pdark.de&amp;blog=6384723&amp;post=626&amp;subd=darkviews&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://blog.pdark.de/2009/06/05/testing-the-impossible-inserting-into-database/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/8a4d6f03a8879432d8563aefbf48e787?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">digulla</media:title>
		</media:content>
	</item>
	</channel>
</rss>
