HOWTO: using multi column keys in MyBatis Sql maps

When you have to deal with a Third normal form (3NF) relational database, you almost always fall in two scenarios:

  • a DB with natural keys as the primary keys of your data
  • a DB with surrogate keys with auto generated integer identities or GUIDs
Said that I prefer to model with the “more normalized” first approach, this results in a more complicated way to query the DB with multiple condition ON clauses in Joins, more and best designed indexes to have good performance, higher skill to develop, maintain and query the DB.
With this approach you can however manage historical data (with the change of the date part of a composite key), you can easily implement inheritance and extension and so on.
Another issue to be aware of,  is that when you opt for the first approach you may have to deal with Object Relational libraries such as MyBatis(Net) I’m talking about here.
When you use MyBatis you can express your relation through the SELECT attribute in the RESULT tag of the RESULTMAP definition.
Suppose we have the following master/detail table definition:
MASTER(M_KEY1, M_KEY2, M_ATTR1, M_ATTR2)
DETAIL(D_KEY1, D_ATTR1, D_FK_M_KEY1, D_FK_M_KEY2)
And you have the following two mapping Classes:
class Master {
    string key1;
    string key2;
    string attr1;
    string attr2;
    List<Detail> details;
}
class Detail {
    string key1;
    string atttr1;
    Master master;
}
Then you can define two result maps:
<resultMaps>
  <resultMap id="masterResult" class="Master">
    <result property="key1" column="M_KEY1" />
    <result property="key2" column="M_KEY2" />
    <result property="attr1" column="M_ATTR1" />
    <result property="attr2" column="M_ATTR2" />
  </resultMap>
  <resultMap id="detailResult" class="Detail">
    <result property="key1" column="D_KEY1" />
    <result property="attr1" column="D_ATTR1" />
  </resultMap>
</resultMaps>
Now you should use the SELECT attribute of the RESULT tag to make MyBatis automatically load the detail list related to a master or a master related to a details and eventually use the LAZYLOAD attribute to defer the execution of the subquery.
The SELECT attribute is used in conjunction with a COLUMN attribute in which you can specify the column to use as the parameter for selection; in our case we have TWO columns, so how this affect the use of SELECT, COLUMN and PARAMETERCLASS?
The multi column mapping of SELECT subqueries is based on Maps/Dictionaries so the mechanism is to build a Map/Dictionary from more than one column to use as a parameter for another query; to the masterResult map we can add:
<result property="details" column="MAP_KEY1=M_KEY1,MAP_KEY2=M_KEY2" select="details.byMaster" />
And in the detailResult map we can similarly add:
<result property="master" column="MAP_KEY1=D_FK_M_KEY1,MAP_KEY2=D_FK_M_KEY2" select="master.byKey" />
The two select statements master.byKey and details.byMaster should be something like this:
<select id="master.byKey" resultMap="masterRes" { parameterClass="System.Collections.IDictionary" (for .NET) OR parameterClass="java.util.Map" (for Java) } >
  SELECT *
  FROM MASTER
  WHERE M_KEY1=#MAP_KEY1# AND M_KEY2=#MAP_KEY2#
</select>
<select id="details.byMaster" resultMap="detailRes" { parameterClass="System.Collections.IDictionary" (for .NET) OR parameterClass="java.util.Map" (for Java) } >
  SELECT *
  FROM DETAIL
  WHERE D_FK_M_KEY1=#MAP_KEY1# AND D_FK_M_KEY2=#MAP_KEY2#
</select>
And that’s it!
Hope some of you may find this helpful.
Annunci

HOWTO: using ServingXML in a Maven project

ServingXML is a powerful library to transform data from one format to another format by using a XML resource to define the transformation.

ServingXML comes with a console app, and also documents an API for embedding the software in a standard Java or J2EE application.

Apache Maven logo.
Image via Wikipedia

So, I decided to use this library in an enterprise integration application where normally I use Apache Maven for the Lifecycle Management. In the public Maven repos I couldn’t find the ServingXML dependency so I built a POM by myself tring to find which dependencies of ServingXML are present on public Maven repos and which are not.

Firstly I downloaded the latest version of ServingXML and extracted it on a local directory.

I adjusted the build-extensions.xml file as follows to obtain a minimal version of the library:

<project basedir="." default="build.extensions">
  <target name="build.extensions">
    <ant antfile="build.xml" dir="servingxml-msv" target="${ext.target}"/>
    <ant antfile="build.xml" dir="servingxml-saxon" target="${ext.target}"/>
    <ant antfile="build.xml" dir="servingxmlx" target="${ext.target}"/>
  </target>
</project>

So I had in my target/servingxml directory the built binary with dependenies in the lib folder. I figured out that some jar was the result of a transitive dependency so I decided to add progressively the libraries to my project using the install goal and then build and run tests to see if it worked.

Finally I obtained this POM:

<?xml version="1.0" encoding="UTF-8"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.servingxml</groupId>
  <artifactId>servingxml</artifactId>
  <version>1.1.2</version>
  <description>Artifactory auto generated POM</description>
<dependencies>
        <dependency>
           <groupId>net.sourceforge.saxon</groupId>
           <artifactId>saxon</artifactId>
           <version>9.1.0.8</version>
        </dependency>
        <dependency>
            <groupId>isorelax</groupId>
            <artifactId>isorelax</artifactId>
            <version>20030108</version>
        </dependency>
        <dependency>
            <groupId>com.sun.msv.datatype.xsd</groupId>
            <artifactId>xsdlib</artifactId>
            <version>2011.1</version>
        </dependency>
        <dependency>
            <groupId>com.servingxml</groupId>
            <artifactId>msv</artifactId>
            <version>1.1.2</version>
        </dependency>
        <dependency>
            <groupId>com.servingxml</groupId>
            <artifactId>saxon</artifactId>
            <version>1.1.2</version>
        </dependency>
        <dependency>
            <groupId>com.servingxml</groupId>
            <artifactId>x</artifactId>
            <version>1.1.2</version>
        </dependency>
    </dependencies>
</project>

This, properly uploaded in my Artifactory toghether with the deployment of all Ant generated jars, gave me the opportunity to build with Maven “minimal embedded ServingXML” applications within my organization.

L’amore visto dai bambini

Bambino con dito in bocca
Image via Wikipedia

Riporto quanto ho trovato su questo sito; se sono risposte vere, sono davvero sorprendenti.

Degli psicologi hanno posto la domanda “Cosa vuol dire amore?” a bambini dai 4 agli 8 anni. Queste le risposte…

L’amore è la prima cosa che si sente, prima che arrivi la cattiveria.
Carlo, 5 anni

Quando nonna aveva l’artrite e non potreva mettersi più lo smalto, nonno lo faceva per lei anche se aveva l’artrite pure lui.
Questo è l’amore.
Rebecca, 8 anni

Quando qualcuno ci ama, il modo che ha di dire il nostro nome è diverso.
Sappiamo che il nostro nome è al sicuro in quella bocca.
Luca, 4 anni

L’amore è quando La ragazza si mette il profumo, il ragazzo il dopobarba, poi escono insieme per annusarsi.
Martina, 5 anni

L’amore è quando esci a mangiare e dai un sacco di patatine fritte a qualcuno senza volere che l’altro le dia a te.
Gianluca, 6 anni

L’amore è quando qualcuno ti fa del male e tu sei molto arrabbiato, ma non strilli per non farlo piangere.
Susanna, 5 anni

L’amore è quella cosa che ci fa sorridere anche quando siamo stanchi.
Tommaso, 4 anni

L’amore è quando mamma fa il caffè per papà e lo assaggia prima per assicurarsi che sia buono.
Daniele, 7 anni

L’amore è quando una donna vecchia e un uomo vecchio sono ancora amici anche se si conoscono bene.
Tommaso, 6 anni

L’amore è quando mamma da a papà il pezzo più buono della torta.
Elena, 5 anni

L’amore è quando il mio cane mi lecca la faccia, anche se l’ho lasciato solo tutta la giornata.
Anna Maria, 4 anni

Non bisogna mai dire ti amo se non è vero. Ma se è vero bisogna dirlo tante volte.
Le persone dimenticano.
Jessica, 8 anni

Penso ai miei bimbi e a quanto è sconcertante a volte quello che riescono a pensare sulle cose del mondo; credo che possano essere frasi che dei bimbi hanno detto o pensato anche se rimango un po’ diffidente; forse è perché non conosco le modalità con cui degli psicologi potrebbero essere riusciti a raccogliere queste testimonianze.

Rimane il fatto che è bello, leggendo, immaginare che un bambino possa aver provato quelle cose.