<?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>Raupachs Welt</title>
	<atom:link href="http://www.raupachs-welt.de/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.raupachs-welt.de</link>
	<description>Oliver Raupachs Java Welt</description>
	<lastBuildDate>Sat, 01 May 2010 13:05:43 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>PL/SQL &#8211; Script: Datensätze nur einmal einfügen</title>
		<link>http://www.raupachs-welt.de/2010/04/plsql-script-datensatze-nur-einmal-einfuegen/</link>
		<comments>http://www.raupachs-welt.de/2010/04/plsql-script-datensatze-nur-einmal-einfuegen/#comments</comments>
		<pubDate>Thu, 29 Apr 2010 12:47:26 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[DB]]></category>
		<category><![CDATA[Oracle]]></category>
		<category><![CDATA[PL/SQL]]></category>
		<category><![CDATA[SQL]]></category>

		<guid isPermaLink="false">http://www.raupachs-welt.de/?p=84</guid>
		<description><![CDATA[Auch der Java-Entwickler muß manchmal zum PL/SQL-Script greifen wenn er z.B. seine Daten initial in die Datenbank laden möchte. Gute Praxis ist dabei natürlich die Möglichkeit ein Datenbank-Script auch mehrmals laufen zu lassen, ohne das dabei die Daten doppelt geladen werden. Als praxistauglich hat sich bei mir die Methode erwiesen dabei erst ein select auf [...]]]></description>
			<content:encoded><![CDATA[<p>Auch der Java-Entwickler muß manchmal zum PL/SQL-Script greifen wenn er z.B. seine Daten initial in die Datenbank laden möchte. Gute Praxis ist dabei natürlich die Möglichkeit ein Datenbank-Script auch mehrmals laufen zu lassen, ohne das dabei die Daten doppelt geladen werden. Als praxistauglich hat sich bei mir die Methode erwiesen dabei erst ein <strong>select</strong> auf den einzufügenden Datensatz zu machen und dabei die Exception &#8220;<strong>NO_DATA_FOUND</strong>&#8221; abzufangen und dort schließlich das <strong>insert</strong> auszuführen.</p>
<p>Das sieht dann z.B. so aus:</p>
<pre class="brush: sql;">
declare
    v_id      number;

begin

 ----------------------------------------------------------------
 -- insert new record
 ----------------------------------------------------------------
  v_id := 159;

   begin
      select t.id
         into v_id
      from myTable t
      where t.id = v_id;

      dbms_output.put_line('existing record ... ' || v_id);

      exception
      when NO_DATA_FOUND then
         insert into myTable
            (id,
             description)
            values
            (v_id,
             'test');

         dbms_output.put_line('inserting record ... ' || v_id);
   end;
end;
</pre>
<p>In diesem Beispiel wird dabei nur auf den Primärschlüssel geprüft. In der Praxis ergeben sich meist bessere Möglichkeiten einen Datensatz zu identifizieren und seine Existenz festzustellen.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.raupachs-welt.de/2010/04/plsql-script-datensatze-nur-einmal-einfuegen/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Einen eigenen ID-Generator für Hibernate</title>
		<link>http://www.raupachs-welt.de/2010/04/einen-eigenen-id-generator-fur-hibernate/</link>
		<comments>http://www.raupachs-welt.de/2010/04/einen-eigenen-id-generator-fur-hibernate/#comments</comments>
		<pubDate>Mon, 26 Apr 2010 09:25:39 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[Hibernate]]></category>
		<category><![CDATA[ID]]></category>
		<category><![CDATA[JPA]]></category>
		<category><![CDATA[Session]]></category>

		<guid isPermaLink="false">http://www.si12.de/?p=71</guid>
		<description><![CDATA[Hibernate bringt von Haus aus schon einige Generatoren für die ID mit. Manchmal sind die Anforderungen an die ID aber spezieller und muß einen eigenen Generator für die Hibernate ID anlegen. In der Java-Klasse, die mit Hibernate persistier werden soll, kann man wie folgt mit JPA annotieren: @Id @Column (name=&#34;MY_ID&#34;, length=16) @GeneratedValue (generator=&#34;GenAccId&#34; ) @GenericGenerator(name=&#34;GenAccId&#34;, [...]]]></description>
			<content:encoded><![CDATA[<p>Hibernate bringt von Haus aus schon einige Generatoren für die ID mit. Manchmal sind die Anforderungen an die ID aber spezieller und muß einen eigenen Generator für die Hibernate ID anlegen.</p>
<p>In der Java-Klasse, die mit Hibernate persistier werden soll, kann man wie folgt mit JPA annotieren:</p>
<pre class="brush: java;">
   @Id
   @Column (name=&quot;MY_ID&quot;, length=16)
   @GeneratedValue (generator=&quot;GenAccId&quot; )
   @GenericGenerator(name=&quot;GenAccId&quot;, strategy = &quot;cc.raupach.MyNumberGenerator&quot;)
   private String myId;
</pre>
<p>Nun kann man die eigentliche Java-Klasse anlegen, die den ID-Generator enthält. Dazu implementier man das von Hibernate bereitgestellte Interface &#8220;<strong>IdentifierGenerator</strong>&#8220;:</p>
<pre class="brush: java;">
public class MyNumberGenerator implements IdentifierGenerator
{
    static String query =&quot;SELECT MySpezialSequence.nextval as myid FROM dual&quot;;

    public Serializable generate(SessionImplementor session, Object object) throws HibernateException
    {
       // hier wird eine eigene Session geöffnet und darin eine eigene Transaktion für Hibernate angelegt
       // um z.B. in einer DB-Abfrage eine ID zu gewinnen.
       Session sessionX=session.getFactory().openSession();
       sessionX.beginTransaction();
       BigDecimal seqNumber = (BigDecimal) sessionX.createSQLQuery (query).uniqueResult();
       sessionX.getTransaction().commit();

       String seqNumberStr = seqNumber.toString();
       String id = &quot;ABCD_&quot; + seqNumberStr;

       return id;
    }
}
</pre>
<p>Der Generator erzeugt in diesem Fall eine numerische ID aus einer eigenen Sequence, die ein Prefix &#8220;ABCD_&#8221; hat. Man kann mit der Methode im Prinzip alles zurückgeben was man will &#8211; nur unique sollte es natürlich sein. Über den Parameter &#8220;object&#8221; hat man auch Zurgriff auf das zu persistierende Object und kann darauf zugreifen und die generierung der ID so z.B. von bestimmten Attributen des Objekts abhängig machen und steuern.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.raupachs-welt.de/2010/04/einen-eigenen-id-generator-fur-hibernate/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Löschen von Datensätzen mit &#8220;exists&#8221;</title>
		<link>http://www.raupachs-welt.de/2010/04/loschen-von-datensatzen-mit-exists/</link>
		<comments>http://www.raupachs-welt.de/2010/04/loschen-von-datensatzen-mit-exists/#comments</comments>
		<pubDate>Mon, 26 Apr 2010 08:53:44 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[DB]]></category>
		<category><![CDATA[Oracle]]></category>

		<guid isPermaLink="false">http://www.si12.de/?p=60</guid>
		<description><![CDATA[Manchmal kommt es vor, dass Datensätze gelöscht werden sollen, die einfach mit ihrer ID in einer anderen - vielleicht temporären - Tabelle gesammelt sind. Dies funktioniert ganz gut mit "exists"...]]></description>
			<content:encoded><![CDATA[<p>Manchmal kommt es vor, dass Datensätze gelöscht werden sollen, die einfach mit ihrer ID in einer anderen &#8211; vielleicht temporären &#8211; Tabelle gesammelt sind. Dies funktioniert ganz gut mit &#8220;exists&#8221;.</p>
<p>Hier ein Beispiel. Gegeben sind die zwei Tabellen:</p>
<pre class="brush: sql;">
create table tbl_a
(
   id integer,
   description varchar(100)
);

create table tbl_b
(
   id integer
);
</pre>
<p>Aus der Tabelle &#8220;tbl_a&#8221; sollen nun alle Datensätze gelöscht werden, die  in der Tabelle &#8220;tbl_b&#8221; enthalten sind &#8211; also für die gilt <strong>tbl_a.id =  tbl_b.id</strong>. Dies funktioniert dann mit:</p>
<pre class="brush: sql;">delete from tbl_a a
 where exists
 (select (1) from tbl_b b where a.id = b.id)
</pre>
<p>Dieses Beispiel basiert auf der Datenbank Oracle.</p>
<pre></pre>
<pre></pre>
]]></content:encoded>
			<wfw:commentRss>http://www.raupachs-welt.de/2010/04/loschen-von-datensatzen-mit-exists/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Einrichten einer minimalen Umgebung für Spring-Batch 2.0</title>
		<link>http://www.raupachs-welt.de/2010/04/einrichten-einer-minimalen-umgebung-fur-spring-batch-2-0/</link>
		<comments>http://www.raupachs-welt.de/2010/04/einrichten-einer-minimalen-umgebung-fur-spring-batch-2-0/#comments</comments>
		<pubDate>Sat, 24 Apr 2010 09:00:29 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[batch]]></category>
		<category><![CDATA[spring]]></category>
		<category><![CDATA[tutorial]]></category>

		<guid isPermaLink="false">http://www.si12.de/?p=4</guid>
		<description><![CDATA[Hier möchte ich beschreiben wie eine Spring-Batch 2.0 Umgebung aufgesetzt wird. Die Anwendung wird später über die Kommandozeile gestartet und besteht nur aus einem einzigen Job mit einem einzigen Step, der den Text "Hallo München" ausgibt.]]></description>
			<content:encoded><![CDATA[<p>Hier möchte ich beschreiben wie eine Spring-Batch 2.0 Umgebung  aufgesetzt wird. Die Anwendung wird später über die Kommandozeile  gestartet und besteht nur aus einem einzigen Job mit einem einzigen  Step, der den Text &#8220;<strong>Hallo München</strong>&#8221; ausgibt.</p>
<h2>Eingesetzte Komponenten</h2>
<p>Für dieses Setup verwende ich folgende Komponenten:</p>
<ul>
<li>Java 1.6</li>
<li>Eclipse 3.5 Galileo</li>
<li>Spring-Batch 2.0.3</li>
<li>Maven 2.1.0</li>
<li>M2Eclipse (Maven-Eclipse Integration)</li>
</ul>
<p>Für das <a href="http://m2eclipse.sonatype.org/" target="_blank">m2eclipse-Plugin</a> kann folgende Eclipse-Update-Seite verwendet werden: <a href="http://m2eclipse.sonatype.org/update/" target="_blank">http://m2eclipse.sonatype.org/update/</a></p>
<h2>Leeres Projekt mit Maven anlegen</h2>
<p>Ich starte mit einem neuen Eclipse-Workspace und lege ein neues  Maven-Projekt an. Dabei wähle ich als <strong>Artifact-ID</strong> den  Typ <strong>maven-archetype-quickstart</strong> aus.</p>
<p style="text-align: center;"><a href="http://www.raupachs-welt.de/wp-content/uploads/2010/04/Maven_archetyp_waehlen-big.jpg" rel="lightbox[4]"><img class="aligncenter size-full wp-image-25" title="Maven_archetyp_waehlen" src="http://www.raupachs-welt.de/wp-content/uploads/2010/04/Maven_archetyp_waehlen.jpg" alt="" width="300" height="280" /></a></p>
<p>Als <strong>Group-ID</strong> habe ich hier<strong> cc.raupach</strong> gewählt und die<strong> Artifact-ID</strong> ist <strong>batch1</strong>.  Dieser Archetyp erzeugt eine ganz einfache Projektstruktur mit Source-  und Test-Verzeichnis mit JAR-Packaging. Zusätzlich lege ich noch den  Source-Folder src/main/resources an. Hier  kommt später die eigentliche Spring-Batch Konfiguration hinein. Der  Verzeichnisbaum sollte dann in etwa so aussehen:</p>
<p style="text-align: center;"><a href="http://www.raupachs-welt.de/wp-content/uploads/2010/04/Maven_archetyp_waehlen_big.jpg" rel="lightbox[4]"> </a></p>
<p style="text-align: center;"><a href="http://www.raupachs-welt.de/wp-content/uploads/2010/04/package-explorer-batch1_big.jpg" rel="lightbox[4]"><img class="aligncenter size-full wp-image-27" title="package-explorer-batch1" src="http://www.raupachs-welt.de/wp-content/uploads/2010/04/package-explorer-batch1.jpg" alt="" width="150" height="180" /></a></p>
<h2>POM anpassen und Dependencies aktualisieren</h2>
<p>Als nächsten Schritt muß das POM von Maven angepasst werden. Dabei füge  ich hier die Bibliotheken <strong>Spring-Batch 2.0.3</strong> und <strong>Commons-Lang  2.1</strong> hinzu.</p>
<p>Mein POM-File sieht dann so aus:</p>
<pre class="brush: xml;">
&lt;project xmlns=&quot;http://maven.apache.org/POM/4.0.0&quot; xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;
	xsi:schemaLocation=&quot;http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd&quot;&gt;
	&lt;modelVersion&gt;4.0.0&lt;/modelVersion&gt;
	&lt;groupId&gt;cc.raupach&lt;/groupId&gt;
	&lt;artifactId&gt;batch1&lt;/artifactId&gt;
	&lt;version&gt;0.0.1-SNAPSHOT&lt;/version&gt;
	&lt;name&gt;batch1&lt;/name&gt;
	&lt;url&gt;http://maven.apache.org&lt;/url&gt;
	&lt;packaging&gt;jar&lt;/packaging&gt;

	&lt;dependencies&gt;
		&lt;dependency&gt;
			&lt;groupId&gt;junit&lt;/groupId&gt;
			&lt;artifactId&gt;junit&lt;/artifactId&gt;
			&lt;version&gt;4.7&lt;/version&gt;
			&lt;scope&gt;test&lt;/scope&gt;
		&lt;/dependency&gt;
		&lt;dependency&gt;
			&lt;groupId&gt;org.springframework.batch&lt;/groupId&gt;
			&lt;artifactId&gt;spring-batch-core&lt;/artifactId&gt;
			&lt;version&gt;2.0.3.RELEASE&lt;/version&gt;
			&lt;type&gt;jar&lt;/type&gt;
			&lt;scope&gt;compile&lt;/scope&gt;
		&lt;/dependency&gt;
		&lt;dependency&gt;
			&lt;groupId&gt;commons-lang&lt;/groupId&gt;
			&lt;artifactId&gt;commons-lang&lt;/artifactId&gt;
			&lt;version&gt;2.1&lt;/version&gt;
		&lt;/dependency&gt;
	&lt;/dependencies&gt;
&lt;/project&gt;
</pre>
<h2>Den STEP anlegen</h2>
<p>Jetzt kan der eigentlich Step angelegt werden, der später den Text &#8220;Hallo München&#8221; ausgibt. Die von Maven angelegt Klasse App.java kann nun gelöscht werden. Sie wird für dieses Projekt nicht benötigt, da Spring-Batch einen eigenen Command-Line-Runner mitbringt, der über ein main  verfügt.</p>
<p>Ich habe die neue Klasse für den Step einfach mal TuNix.java genannt. Hier ist sie:</p>
<pre class="brush: java;">
package cc.raupach.batch1;

import org.springframework.batch.core.StepContribution;
import org.springframework.batch.core.scope.context.ChunkContext;
import org.springframework.batch.core.step.tasklet.Tasklet;
import org.springframework.batch.repeat.RepeatStatus;

public class TuNix implements Tasklet
{

   public RepeatStatus execute(StepContribution arg0, ChunkContext arg1) throws Exception
   {
      System.out.println(&quot;Hallo München.&quot;);
      return RepeatStatus.FINISHED;
   }
}
</pre>
<p>Der Name stimmt nicht ganz, wie man sieht tut die Klasse natürlich schon etwas. Sie gibt ja den Text aus. Die Klasse implementier hier das Intaface Tasklet mit der Methode execute. Ein Tasklet ist vergleichbar mit einer einfachen Prozedur, die aufgerufen wird. Also ohne eigentliche Datenverarbeitung in Form von Items.</p>
<h2>Spring-Batch konfigurieren</h2>
<p>Nun geht es weiter mit der eigentlichen Konfiguration von  Spring-Batch, in der alles zusammengefügt wird. Wie immer bei Spring ist  es wieder eine XML-Datei. Der Name ist beliebig und ich habe sie hier  einfach mal hello-spring-batch.xml genannt  und in src/main/resources abgelegt:</p>
<pre class="brush: xml;">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;beans:beans xmlns=&quot;http://www.springframework.org/schema/batch&quot;
     xmlns:beans=&quot;http://www.springframework.org/schema/beans&quot;
     xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;
     xsi:schemaLocation=&quot;

http://www.springframework.org/schema/beans

http://www.springframework.org/schema/beans/spring-beans-2.0.xsd

http://www.springframework.org/schema/batch

http://www.springframework.org/schema/batch/spring-batch-2.0.xsd&quot;&gt;

	&lt;!-- Transaktions-Manager --&gt;
	&lt;beans:bean id=&quot;transactionManager&quot;
      class=&quot;org.springframework.batch.support.transaction.ResourcelessTransactionManager&quot;/&gt;

	&lt;!-- Memory-Repository --&gt;
	&lt;beans:bean id=&quot;jobRepository&quot;
      class=&quot;org.springframework.batch.core.repository.support.MapJobRepositoryFactoryBean&quot;&gt;
		&lt;beans:property name=&quot;transactionManager&quot;
           ref=&quot;transactionManager&quot;/&gt;
	&lt;/beans:bean&gt;

	&lt;!-- JobLaunscher --&gt;
	&lt;beans:bean id=&quot;jobLauncher&quot;
       class=&quot;org.springframework.batch.core.launch.support.SimpleJobLauncher&quot;&gt;
		&lt;beans:property name=&quot;jobRepository&quot;
           ref=&quot;jobRepository&quot; /&gt;
	&lt;/beans:bean&gt;

	&lt;!--  Job --&gt;
	&lt;job id=&quot;mySampleJob&quot; job-repository=&quot;jobRepository&quot;&gt;
		&lt;step id=&quot;mySampleStep&quot;&gt;
			&lt;tasklet ref=&quot;myTuNixTasklet&quot; /&gt;
		&lt;/step&gt;
	&lt;/job&gt;

	&lt;!-- Step --&gt;
	&lt;beans:bean id=&quot;myTuNixTasklet&quot; class=&quot;cc.raupach.batch1.TuNix&quot;/&gt;

&lt;/beans:beans&gt;
</pre>
<p>Für die Spring-Batch Konfiguration werden hier die folgenen Teile  benötigt:</p>
<ul>
<li><strong>Job-Repository</strong> (Zeile 15-20): In diesem  Fall handelt es sich um eine Memory-Repository. Das bedeutet, der  Zustand der einzelnen Jobs geht nacht dem beenden der Anwendung wieder  verloren.</li>
<li><strong>Transaktions-Manager</strong> (Zeile 11-13): Hier auch  nur der Default-Transaktionsmanager, da ja hier keine echten  Transaktionen existieren.</li>
<li><strong>Job-Launcher</strong> (Zeile 22-27): Der  Job-Launcher versorgt den Job mit zusätzlichen Parametern</li>
<li>Der <strong>Job</strong> (Zeile 29-34): Er besteht in diesem  Fall nur aus einem einzigen Step</li>
<li>Der <strong>Step</strong> (Zeile 36-37): Hier wird die  Klasse TuNix konfiguriert, die den Text ausgibt.</li>
</ul>
<h2>Eine Eclipse Run-Configuration anlegen</h2>
<p>Jetzt muß noch Eclipse so konfiguriertwerden, dass Spring-Batch  richtig gestartet werden kann. Dazu lege ich eine neue Run-Config in  Eclipse an. Wichtig dabei ist, dass die main  aus Spring-Batch kommt, nämlich diese:</p>
<pre>org.springframework.batch.core.launch.support.CommandLineJobRunner</pre>
<p style="text-align: center;"><a href="http://www.raupachs-welt.de/wp-content/uploads/2010/04/eclipse-run-config-big.jpg" rel="lightbox[4]"><img class="aligncenter size-medium wp-image-33" title="eclipse-run-config" src="http://www.raupachs-welt.de/wp-content/uploads/2010/04/eclipse-run-config-300x236.jpg" alt="" width="300" height="236" /></a></p>
<p>Zusätzlich wichtig ist nun noch den CommandLineJobRunner  von Spring mit den richtigen Parametern zu versorgen. Diese kann man  auf dem Reiter &#8220;Arguments&#8221; in der Run-Config eintragen. Der CommandLineJobRunner benötigt als ersten Parameter  den Namen der XML-Config, also in diesem Fall hello-spring-batch.xml  und als zweiten Parametern den Namen des Jobs, der gestartet werden  soll. Das ist hier der Name mySampleJob. So  es dann aus:</p>
<p style="text-align: center;"><a href="http://www.raupachs-welt.de/wp-content/uploads/2010/04/eclipse-run-config-argumente.jpg" rel="lightbox[4]"><img class="aligncenter size-full wp-image-35" title="eclipse-run-config-argumente" src="http://www.raupachs-welt.de/wp-content/uploads/2010/04/eclipse-run-config-argumente.jpg" alt="" width="261" height="93" /></a></p>
<p>Nach dem Start sieht man folgenen Output in der Console. Es hat  funktioniert:</p>
<p style="text-align: center;"><a href="http://www.raupachs-welt.de/wp-content/uploads/2010/04/Console-output-big.jpg" rel="lightbox[4]"><img class="aligncenter size-medium wp-image-36" title="Console-output" src="http://www.raupachs-welt.de/wp-content/uploads/2010/04/Console-output-300x163.jpg" alt="" width="300" height="163" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.raupachs-welt.de/2010/04/einrichten-einer-minimalen-umgebung-fur-spring-batch-2-0/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

