Meine neue Wohnung

IMG_0762.JPG

Finde das Foto so gut, dass ich es mal in mein Blog posten wollte.
Außerdem kann ich so auch die Blogfunktion von flickr testen…die anscheinend ziemlich schlecht ist…

Glücklicherweise habe ich mir das Macheist Bundle gesichert.

Die bei weitem beste Applikation in dem Bundle ist Textmate in dem ich diesen Post gerade schreibe…

Sehr gut!

Am Wochenende war mein Diplomball mit der Übergabe der Zeugnisse. Im feierlichen Rahmen haben meine Kommilitonen und ich unsere Diplomurkunden erhalten.

Und wie man dem Titel dieser Post entnehmen kann war das Ergebnis doch relativ zufriedenstellend! 🙂

Ziel erreicht

Habe heute meine Diplomarbeit präsentiert.

D.h. dieses Blog wird ab sofort nicht mehr das Überthema der Arbeit haben, sondern zu meinem privaten und Entwicklerblog umfunktioniert.

Für die die es interessiert: Die Diplomarbeit ist sehr gut angekommen und ich hoffe, dass die Note das auch wiederspiegeln wird :-D.

Mein Gesichtsausdruck nach Präsentation der Diplomarbeit :-D

1000er Marke geknackt

Heute morgen hat dieses Blog die 1000-Hit-Marke geknackt.
Und gestern war sogar der Tag mit den meisten Besuchen bisher.
Nicht schlecht nach gerade einmal zwei Monaten und für die exotischen Themen, die hier behandelt werden!

Wenn man Suchformulare hat, bei denen alle oder viele Suchparameter optional sind, hat man immer das Problem, wie man die SQL Abfragen dafür gestalltet.

Man könnte entweder für jede Kombination eine eigene Query schreiben oder eine Query von Hand mit unzähligen ifs zusammenschustern.

Ein solches Vorgehen ist jedoch sehr fehleranfällig, weil sich so leicht Fehler in die SQL Query, die am Ende herauskommt, einschleichen.

Hibernate bietet auch hier eine elegante Lösung an: die Criteria API. Hiermit lassen sich Querys auf einfache Art und Weise zusammenbauen, mit allem was dazugehört (Joins usw.). Um die eigentliche Generierung des SELECT Statements kümmert sich das erprobte Framework.

Solch ein Criteria Objekt ist eigentlich nichts anderes als eine leere Hibernate Query, an die man Suchkriteren anhängen kann.

//Das Criteria Object erzeugen
Criteria purchaserCriteria = hibSession.createCriteria(Einkaeufers.class);

//Normales Kriterium
if (einkaeuferName != null)
{
purchaserCriteria.add(Expression.like(„einkaeuferName“, einkaeuferName);
}

Expression.like() gibt ein Criterion zurück, dass für die add-Methode des Criteria Objektes benötigt wird. Expression hat für alle Standard-SQL Operatoren statische Methoden, wie eq (=), le (<=), gt (>) usw.

Für Joins wird einfach ein weiteres Criteria Objekt erzeugt, um dafür wiederum eine Expression angeben zu können.
Der erste Parameter der createCriteria() Methode ist der Name des Properties in der hbm-Datei (funktionenSet), der zweite ein frei wählbarer Alias, den man im Criterion nutzen kann (funktionen.funtkionId).

//Kriterium mit einem Join
if (functionId > 0)
{
purchaserCriteria.createCriteria(„funktionenSet“, „funktionen“)
.add(Expression.eq(„funktionen.funktionId“, new Integer(functionId)));
}

//Kriterium mit zwei Joins
if (countryId > 0)
{
purchaserCriteria.createCriteria(„standort“, „standort“).createCriteria(„laender“, „laender“).add(Expression.eq(„laender.laenderId“, new Integer(countryId)));
}

ResultTransformer können ebenfalls praktisch sein (hier DISTINCT):

//Ergebnis muss Distinct sein
purchaserCriteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);

Sortierung ist natürlich auch möglich:

//Order hinzufügen (über einen Join mit Alias (hier wird kein extra Criteria Object erzeugt))
purchaserCriteria.createAlias(„tEinkaeufer“, „tEinkaeufer“).addOrder(Order.asc(„tEinkaeufer.telvName“));

Wenn alle Suchparameter angegeben sind, kann wie bei der Query API list() ausgeführt werden.

//Abfrage ausführen
List purchaserList = purchaserCriteria.list();

Alles in allem lässt sich sagen, dass man sich mit dieser API sehr viel Arbeit und Ärger ersparen kann.

Wieder ein Grund mehr für die Verwendung von Hibernate!

Eine sehr gute Einführung in die API gibt es bei devx.

SSL und somit auch https nutzen eine asysmetrische Verschlüsselung, d.h. der Client benötigt den öffentlichen Schlüssel des Servers, mit dem er die Nachricht für diesen verschlüsseln kann.

Um mit einem Java-WebService-Client eine SSL Verbindung herzustellen, muss das Zertifikat des Servers in den JVM Keystore importiert werden. Man kann es entweder in den Standardkeystore importieren, der je nach Betriebssystem an verschiedenen Orten liegen kann. Bei Windows liegt er normalerweise hier:

C:\Dokumente und Einstellungen\<user>\.keystore

Um einen Zertifikat und somit einen Schlüssel in diese Datei zu importieren, kann man das Keytool von SUN nutzen, welches unter %JAVA_HOME%\bin\keytool.exe zu finden ist. Ein Import eines Zertifikates sieht folgendermaßen aus:

keytool -import -v -alias <keyalias – frei wählbar> -file <Speicherort des Zertifikats> -storepass <standard:changeit>

Leider scheint Tomcat warum auch immer partout nicht auf diese Datei zuzugreifen, also habe ich eine eigene Datei mit dem zusätzlichen Parameter -keystore <datei.keystore> erstellt.

Nun musste ich auch noch beim Initialisieren meines Servlet, welches den WebService über https aufruft das System-Property javax.net.ssl.trustStore setzen:

System.setProperty(„javax.net.ssl.trustStore“, „datei.keystore“);

Für den Client MUSS es das trustStore-Property sein und NICHT das keyStore-Property.

Das ganze kann man natürlich auch Tomcat als Startparameter mit übergeben, wie hier beschrieben.

Update: Der java-weite Keystore liegt in JAVA_HOME\jre\lib\security\cacerts

Nach längerem Suchen habe ich endlich verstanden, wie man n:m-Beziehungen in Hibernate am besten mappt.
Für die Verwaltung von solchen Beziehungen benötigt man in relationalen Datenbanken eine Beziehungstabelle.

Nehmen wir an es gibt 3 Tabellen:

News, Category und NewsCategory.

Eine News kann mehreren Categories zugeordnet sein und die Categories können natürlich in verschiedenen News benutzt werden. NewsCategory ist somit die Relationship-Tabelle.

Folgende Felder sind definiert (Auszug):

  • News-Tabelle: newsId(PK)
  • Category-Tabelle: categoryId(PK)
  • NewsCategory-Tabelle: newsCategoryId(PK), newsId(FK), categoryId(FK)

In der news.hbm.xml-Mapping-Datei definiert man ein Set, das die Beziehung zu den Categories abbildet:

<set name=“categories“ table=“NewsCategory“>
<key column=“newsId“ />
<many-to-many class=“net.vland.demo.Category“ column=“categoryId“/>
</set>

Das gleiche in der category.hbm.xml

<set name=“news“ table=“NewsCategory“>
<key column=“categoryId“ />
<many-to-many class=“net.vland.demo.News“ column=“newsId“/>
</set>

Nun muss man nur noch in den POJOs einfache Sets mit den definierten Namen erzeugen und das war’s. Es ist jetzt möglich ohne Umwege über die Beziehungstabelle die Daten auszulesen, z.B.:

Set categories = news.getCategories();

Anmerkung: Hibernate wirft eine Exception, wenn für einen Datensatz kein „Beziehungs-Set“ da ist. Dies kann durch not-found=“ignore“ im <many-to-many>-Tag unterbunden werden.

Wenn ein Hibernate-Property mit einem Kleinbuchstaben anfängt und darauf ein Groß-Buchstabe folgt, funktionieren die Getter und Setter, die Eclipse generiert, nicht mehr.

Das Property heißt tEinkaeufer.

Dafür hat Eclipse diese Getter und Setter generiert:

public TEinkaeufer getTEinkaeufer()
{
return tEinkaeufer;
}

public void setTEinkaeufer(TEinkaeufer einkaeufer)
{
tEinkaeufer = einkaeufer;
}

Beim initialisieren von Hibernate wurde dann folgender Fehler geworfen:

Initial SessionFactory creation failed.org.hibernate.PropertyNotFoundException: Could not find a getter for tEinkaeufer in class …

Daraufhin habe ich den Code folgendermaßen abgeändert:

public TEinkaeufer gettEinkaeufer()
{
return tEinkaeufer;
}

public void settEinkaeufer(TEinkaeufer einkaeufer)
{
tEinkaeufer = einkaeufer;
}

Und nun funktioniert es, was mich ein bisschen wundert.

Ich weiß nicht ob das ein Fehler in Hibernate ist, oder ob das so gewollt ist. Kann mir nicht vorstellen wieso…

« Vorherige SeiteNächste Seite »