Spring MVC Framework 3.0.1, Indexed Properties

Achtung, wer noch springframework 3.0.1 verwendet: Hier gibt’s einen schweren Bug, was Indexed Properties betrifft. Formulardaten mit Index wie:


<form:input path="myArray[0]"/>

werden nicht korrekt submitted: http://jira.springframework.org/browse/SPR-6871

Also schleunigst auf 3.0.2 updaten.

Hat mich gerade 4h gekostet.

iBatis und DB2: Nicht erkannter JDBC-Typ: 0

Dieser Fehler tritt auf, wenn iBatis ein Objekt zu speichern versucht, bei dem Properties “null” sind.
Um diesen Fehler zu verhindern, muss man in der SQL Map den SQL Datentypen der Spalte mit angeben (hier DATE):

insert into myTable (myName, myDate) values (#name# , #date:DATE#)

Siehe auch im Spring Forum

Buchtipp: Stripes: …and Java Web Development Is Fun Again

Gibt es jetzt schon eine Weile, ist aber wirklich ein sehr gutes Buch über Stripes und jedem, der keine Probleme mit englischen Computerbüchern hat, sehr zu empfehlen. Der Autor ist ein erfahrener Java Webprogrammierer- und auch Tim Fennel, der Erfinder von Stripes, gibt Tipps in diesem Buch.

http://www.pragprog.com/titles/fdstr/stripes

Offtopic: SO 36 bleibt

Immer wieder unglaublich… Da wohnen Leute in einer Großstadt und erwarten ländliche Ruhe. Ich kann’s nicht fassen.


SO36 Bleibt

IBatis Tipps (I): Enumerations

Ich verwende gerne Java Enumerations, wenn ein Datenbankfeld nur eine bestimmte Anzahl an Typen enthalten kann . Ein Beispiel wäre eine Tabelle CONTACTS (ich gebe mal nicht alle Felder an) mit dem Feld “TYPE”, das PRIVATE,BUSINESS oder OTHER enthalten kann:


CREATE TABLE CONTACTS (
	ID INTEGER NOT NULL,
        TYPE AS VARCHAR(24),
        NAME VARCHAR(50) NOT NULL,
        .
        .
        .
	PRIMARY KEY (ID)
);

Für das Datenbankfeld TYPE erstelle ich folgende Enumeration:
Nehmen wir mal an, wir haben folgende Enumeration:


public enum ContactType {
     PRIVATE, BUSINESS, OTHER
}

Und dann noch folgendes Modell:


package de.binnichda.comp;
public class Contact {
   private Long id;
   private ContactType type;
   private String name;

   /* Und natürlich die zugehörigen Getter/Setter ... */
}

Noch kann man jetzt leider noch nicht viel mit der Enumeration anfangen, denn IBatis muss noch wissen, wie es diesen Typen behandeln soll. Dazu muss man eine Klasse erstellen, die “TypeHandlerCallback” implementiert. Mit Java 5 bietet es sich an, das ganze generisch zu erschlagen:


package de.binnichda.comp;
@SuppressWarnings("unchecked")
public class GenericEnumHandlerCallback <E extends Enum> implements TypeHandlerCallback {

   private Class<E> enumClass;

   public GenericEnumHandlerCallback(Class<E> enumClass) {
      this.enumClass = enumClass;
   }

   private Class<E> getEnumClass() { return enumClass; }

   public void setParameter(ParameterSetter setter, Object parameter) throws SQLException {
      setter.setString(parameter.toString());
   }

   public Object getResult(ResultGetter getter) throws SQLException {
      return valueOf(getter.getString());
   }

   public Object valueOf(String s) {

      if (s == null)
         return null;
      else
         return Enum.valueOf(getEnumClass(), s);
   }

}

Mein konkreter ContactTypeHandler muss dann folgendermaßen aussehen:


package de.binnichda.comp;
public class ContactTypeHandlerCallback extends
      GenericEnumHandlerCallback<ContactType> {

   public ContactTypeHandlerCallback() {
      super(ContactType.class);
   }
}

Jetzt noch den TypeHandlerCallback IBatis bekannt geben:


<typeHandler javaType="de.binnichda.comp.ContactType" callback="de.binnichda.comp.ContactTypeHandlerCallback"/>

Fertig, die Enumeration kann verwendet werden:


Contact contact = new Contact();
contact.setName("Felix Meinhold");
contact.setType(ContactType.PRIVATE);

contactDao.save(contact);

Oder folgendes IBatis Mapping, um mehrere Contact Typen abzufragen:


    <select id = "findByContacts"  parameterClass="map" resultMap = "contactMap">
        SELECT * FROM CONTACTS
        <isNotEmpty property="contactTypes" prepend="WHERE TYPE_ IN ">
            <iterate property="contactTypes"
             open="(" close=")"
             conjunction=",">#contactTypes[]#</iterate>
        </isNotEmpty>
    </select>

jQuery Selektoren II

Vergesse ich immer wieder…

Finde alle Elemente ab einem bestimmten Element (hier this) des Dokuments:


$('input', this).each(....);

Es gibt einen ZWEITEN Parameter für $() ;-)

jQuery Selektoren

jQuery ist cool. Das sollte inzwischen Kinderwissen (so wie in “Italien sieht wie ein Stiefel aus”) sein.

Dieser Artikel wird eine lose Sammlung von jQuery Selektoren.

Suche alle Elemente A, die eine Bestimmte css-Klasse haben und kein Element B als Kindknoten, das eine andere bestimmte css-Klasse hat und füge einen “*” hinzu.


$('.required:not(:has(div.error-message))').each(function() {
$(this).append('<span>*</span>');
});

Problem bei der Installation von CakePHP in Apache UserDir

Kostete mich einiges Googlen…

Installiert man cakephp in das UserDir von apache, also zum Beispiel nach http://localhost/~felix/cakephp, dann
muss man die mitgelieferte .htaccess Datei in im cakePHP root und in app/webroot mit


RewriteBase /~felix/cakephp

erweitern.

Nutze den Eclipse QuickFix! So oft es geht.

Ich denke, das weiß fast jeder, aber manchmal hat man ja Paradeiser auf den Augen.

Für Methoden:

Schreib erst den Methodenaufruf mit allen Parametern, und erzeuge dann die Method mit QuickFix.

Für Getter / Setter:

Deklariere erst das Feld (private) und erzeuge dann die Getter / Setter mit QuickFix.

Screenshot Eclipse Quick Fix

Für Exceptions, für Konstruktoren und und und…

Gnome und Windows Taste

Gestern mal wieder von XFCE auf GNOME gewechselt und dabei festgestellt, dass die Windows-Taste, die ich in Verbindung mit F1-F4 zum Umschalten der Desktops nutze, sich standardmäßig unter Gnome nicht als “Modifier” verhält. Dies lässt sich erst erreichen, wenn man unter

Preferences -> Keyboard -> Layouts -> Layout Options -> Alt/Win Key behavior -> Hyper is mapped to the Win-Keys

anschaltet.. Wie intuitiv.