« September 2007 | Main | November 2007 »

October 2007 Archives

October 2, 2007

Update & Design Entscheidungen

SOOOO die ersten Erfahrungen mit Java Servlets und Beans sind gemacht.
Letztendlich lässt sich eines sagen: Die Fehlermeldungen sind nicht wirklich sooo hilfreich.

Auf den Weg zu einer ersten funktionierenden Implimentierung einer User Klasse habe ich folgende Dinge (erstmal vorläufig) entschieden um mal ein lauffähiges Grundsystem zu haben:

1. Alle meine Klassen werden im Package de.hausswolff.Diplom ihren Platz finden. Ob ich die Hirachie dann noch aufbreche muss ich dann noch sehen.

2. Es gibt eine Datanbankklasse, die mir den Zugriff auf die Datenbank kapselt. Bisher ist das einfach eine Sammlung aller nötigen MySQL Funktionen (wie Update/Queries, Rückgabe der erhaltenen Einträge usw.). Diese Klasse initialisiert beim ersten Aufruf auch alle benötigten Tables (d.h. Letztendlich muss beim ersten Aufruf nur eine beschreibbare Datenbank zur Verfügung stehen)

3. Es gibt eine (statische) Config Klasse, die hauptsächlich aus Attributen besteht und u.a. die Datenbank-Einstellungen, sowei ein Flag für den LDAP Zugriff enthält. Hier soll dann auch gespeichert werden, ob die Datenbank schon initialisert ist oder nicht - wie das ablaufen soll, muss ich dann noch sehen.

nachfolgende Festlegungen haben nur im Kontext einer flachen Benutzertabelle, welche als vorläufiger Ersatz einer LDAP Authentifizierung dient.

4. Ein Username ist eindeutig. Es gibt zwar für jeden Benutzer eine eindeutige ID, allerdings soll kein User einen schon vorhandenen Usernamen benutzen dürfen (dies wird durch die setName methode, welche bei einer Benutzererstellung aufgerufen wird überprüft und ggf. mit einer Fehlermeldung quittiert)

5. Das Password wird in der Datenbank als md5 Hash abgelegt. Eine Überprüfung auf Richtigkeit eines Passwortes erfolg nur über die md5 hashes.

October 6, 2007

Was bisher so geschieht...

Moin...
Ich wollte mal wieder ein wenig Feedback geben, woran ich bisher so sitze...
Letztendlich bin ich endlich mit einer schönen Datenbankklasse ausgestattet, die mir auch die Dinge bietet, auf die ich angewiesen sein werde - ob da jetzt noch etwas dazu kommt, wird sich zeigen, aber erstmal reicht mir das, was bisher vorhanden ist. Zudem bin ich auf ein paar Besonderheiten von JSP/Java und MySQL gestossen, die in meinen Augen recht unlogisch sind, aber nunja, vielleicht gibt sich das noch.
Mein bisheriger Plan ist es, jetzt erstmal die Grundfunktionen des Servers mit einer einfachen HTML Oberfläche zu erstellen, um dann den Client mit Hilfe von YUI dynamischer zu gestallten.

Aber jetzt erstmall ein Überblick über die Klassen:


System.png


Die statische Config Klasse ist erst später hinzugekommen, sodass ich die Attribute aus der Datenbankklasse, welche den Zugriff betreffen wohl dann entferne und die Benutzerdaten zentral in der Config Klasse speichere.
Ich habe jetzt auch schon erste Tests mit einer Session hinter mir, aber das Klassendesign ist noch sehr gewöhnungsbedürftig ^^.

Die Klasse TOOLS soll einfach zur Sammlung verschiedener Funktionen dienen.
Die md5 Methode dient einfach dazu, einen gegeben String als md5 Summe zurückzugeben. Dies brauche ich u.a. für die Passwörter.

Sobald ich die erste HTML Oberfläche habe (die dann einfaches Anmelden, Erstellen und Auflisten von Einträgen beherrschen wird, werd ich erste Funktionstests machen.
Das Schöne, was ich an Eclipse gefunden habe ist, dass man per Vorgabe einfache TextKlassen für Klassen erstellen kann. Dort werden alle Methoden einmal aufgerufen.
Ob das für ein Unit Testing ausreicht muss ich dann noch mal sehen.

Achja... Java und MySQL: Die erhaltenen Einträge aus der Datenbank speichert Java in einem sog. Resultset. Mit der methode next() kann man die verschiedenen Einträge durchblättern. Das komische ist nur, dass wenn - nachweislich - nur ein Eintrag vorhanden ist, muss man dennoch einmal die next() methode aufrufen.
Also muss man von 0. Eintrag auf den 1. blättern? O_o. Meiner Meinung nach irgendwie unnlogisch. Dementsprechend hat mich das auch ein wenig aufgehalten.
Betroffen war u.a. diese Methode aus der Klasse User:

	public void load(){
		this.DB.Query("SELECT `ID`, `password` FROM `users` WHERE `name` = '"+this.name+"' ");
		try {
			ResultSet res = this.DB.getLastResult();
			System.out.println(res.toString());
			res.next();
			this.ID = res.getInt("ID");
			this.password = res.getString("password");
		}catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

Ob ich jetzt das "erste Blättern" in der getLastResult() unterbringe habe ich mir noch nicht überlegt.

Wünsche allen frohes Schaffen und ein schönes Rest-Wochenende!

October 9, 2007

Betr. JPA

Bisher hat der Umbau der vorhanden Klassen hinsichtlich der Nutzung von JPA promblemloser funktioniert als gedacht. Bisher versuche ich halt nur, das User Objekt aus der Tabelle User auszulesen.
Letztendlich muss ich aber mein bisheriges Konzept soweit umstellen, dass ich die Validierung von Eingaben aus der User Klasse in eine sperate Application Klasse auslagere.
Allen anschein nach klappt das Laden der User Klasse mit Hilfe eines EntityManagers fehlerlos, allerdings scheint es da an einigen Stellen noch zu Problemen zu kommen.

Nach der Überarbeitung sieht die User Klasse nun wie folgt aus:

Screenshot1.png

Die Methoden isLogin and isWithName werden dann wahrscheinlich auch ausgelagert werden müssen. Das Attribut error wird wohl einer Fehlerbehandlungsklasse weichen und in Folge dessen als Sammlung von Exceptions implimentiert werden.

Als Primary Key habe ich mich jetzt für das Attribut Name entschieden, da es scheinbar nur möglich ist, die find Methode des EntityManagers anhand eines Primary keys zu nutzen und ich aller Vorraussicht nach eher nach Namen als nach IDs suchen werde.

Das Laden des Objektes passiert nun in einer neuen Klasse Application:

Screenshot.png

Leider wird mir bei der Methode showID() eine NullPointerException geworfen, die ich noch nicht ganz nachvollziehen kann :-/. Letztendlich wird mir JPA aber denke ich eine Menge an Arbeit abnehmen, sobald es erstmal stabil läuft.

Bei Sun habe ich allerdings noch ein Beispiel gefunden, was wie perfekt für mich zu sein scheint, weil es schon ziemlich viel von dem behandelt, was ich eigentlich machen möchte [1]

October 22, 2007

JPA YEEHA!

Besser später als nie, hier also dann mal - nach laaaanger Zeit mal wieder - mein aktueller Status. Mittlerweile bin ich ein ganzes Stück weiter und so fange ich sogar an, dem ganzen System von Persistence etwas abgewinnen zu können. Einzig die Frage bleibt, wieso JPA per default partout alle Feldnamen als groß schreibt. Naja das wird sich sicherlich auch noch klären. Aber zuersteinmal der Reihe nach: Das - anfängliche Problem, dass ich ja einen Integer Primary Key brauche, aber auch zum Beispiel auch ein User Objekt anhand eines Namens (der ja nach meiner Definition auch eindeutig sein soll) erstellen will, ergab sich die Zwickmühle, dass es ein System geben muss, welche einem quasi einfache SQL Searches erlaubt... gibt es auch. Anhand einer Präsentation, von Phillip fand sich dann auch eine recht kurze (und demnach schmerzlose) Lösung:
@Entity
@Table(name = "Users")
@NamedQuery(name = "findWithName", query = "SELECT u FROM User u WHERE u.name = :Name")
public class User {
....
}
Das sagt der Klasse, dass sie, wenn ich eine Query namens ("findWithName") ausführe, das nachfolgende SQL Statement benutzen soll und demnach auch den Parameter 'Name' Der Aufruf schaut dann so aus:
User user = (User) em.createNamedQuery("findWithName").setParameter("Name", "TestUser").getSingleResult();
Nunja ein schöner, langer Aufruf. Aber immerhin wird mir ein User Objekt erstellt, wenn ein User mit Namen 'TestUser' existiert! Kommen wir zum nächsten Punkt - mein Lieblingspunkt an diesem Morgen, weil das mich ziemlich viel Zeit und Schweizß gekostet hat (obwohls doch eigentlich so einfach ist) - die Kardinalitäten - ODER AUCH -" wie papern, wer n Eintrag an'nen User?" Ich bin in mich gegangen und kam mit der Entscheidung aus mir (sagt man das so?), dass ich für jeden Eintrag, der von User A nach User B geschickt wird, ein Eintrag in der Datenbank erstellt wird. Also selbst, wenn User A an B und C die gleiche Aufgabe verteilen würde, würden zwei Einträge erstellt. Ich weiß, dass es dann recht unmöglich ist, zum Beispiel zwei User für eine Aufgabe vorzusehen und diese Aufgabe dann bei User B erledigt ist und bei User C noch offen - letztendlich ging es mir auch ersteinmal darum, die Abhängigkeiten hin zu bekommen. Also erstmal die Veriante mit Stützrädern (zwei Tabellen) und dann hinterher (so morgen) schau ich mal, ob ich das auch freihändig schaffe (so drei Tabellen). Letztendlich schaut das mit JPA ähnlich aus wie bei Willem und seinen RoR (gabs da nich mal n Lied mit RoR, RoR, RoR the Boat? aber ich glaube das war Row... egal). Also vielleicht zuerst einmal die beiden Klassen und wie diese zusammenhängen: class%20diagram.png Ja die Attribute laden quasi dazu ein, auf eine 3. Tabelle auszulagern ;-). Es gibt also zwischen User und Entry exact zwei 1-zu-N Beziehungen: 1. Hat ein User genau eine Inbox mit N erhaltenen Entries 2. Hat ein User genau eine Outbox mit N versandten Entries Da Willem nich Ruhe geben wollte, habe ich die Tabellen gleich mal Pluralisiert (okay ist auch sonst ne ganz gute Idee) und die IDs _id getauft. Für JPA geht man nun wie folgt vor:
...
public class User {
...
	@OneToMany(mappedBy = "recipient")
	private Collection inbox;
	@OneToMany(mappedBy = "sender")
	private Collection outbox;
...
}
...
sagt einem, dass jeweils die Attribute (eigentlich die Items aus den Collections) inbox und outbox an das Attribut (und hierbei geht es wohl wirklich um das Objekt ansich) "recipient"/ "sender" gemapped werden. In der Klasse Entry muss dann natürlich quasi "das Kind konfiguriert werden" (das klingt jetzt seltsam aber im Moment fällt mir nix gescheiteres ein):
...
public class Entry {
...
	@ManyToOne()
    @JoinColumn(name="recipient_id")
	private User recipient;
	@ManyToOne()
    @JoinColumn(name="sender_id")
	private User sender;
...
}
...
Na gemerkt? ManyToOne anstatt OneToMany....ach war klar? Na,... okay :-). Nun werden halt nur noch schnell die Feldnamen aus der DB Table angegeben und besagte Objekte erstellt ( "recipient"/ "sender" ). Geht ja eigentlich ganz schnell... Das Setten/Getten probiere ich dann mal morgen und dann auch gerne mit 1+1+1 = 3 Tabellen. Gibt einem ja dann doch ein wenig mehr Möglichkeiten. Das EJB3 Buch ist übrigens gut. Man liest, schreibt, sucht dann noch nen anderes Beispiel und dann versteht man es erst ;-). Nach und nachen rücken aber erster und letzter Schritt immer näher zusammen. Ich wünsche allen eine erfolgreiche Woche.

erster Eintrag erstellt!

Mittlerweile konnte ich jetzt auch schon den ersten Eintrag erstellen. Das ganze schaut noch recht umständlich aus, weil noch so gar keine Frontends existieren:
	public String addEntry(){
		User recipient = (User)em.find(User.class, 3);
		Entry important = new Entry();
		Calendar cal = Calendar.getInstance();
		cal.set(2007, 12, 15);
		Date end = (Date) cal.getTime();
		important.setSender(user);
		important.setRecipient(recipient);
		important.setPriority(1);
		important.setStatus(10);
		important.setTitle("start with ADAM&EVA");
		important.setDeadLine(end);
		important.setSendDate(new Date());
		important.setContent("no text");
		em.getTransaction().begin();
		em.persist(important);
		em.getTransaction().commit();
		em.close();		
		return important.toString();
	}
Es gibt - natürlich - den Benutzer mit ID 3 (als Empfänger) schon und auch user ist als Attribut der Klasse schon gesetzt. Letztendlich wird der Eintrag auch abgespeichert - wenn man so will die erste wirklich sinnvolle Funktion :-). Mittlerweile habe ich mich dazu entschlossen gemäß MVC alle POJOs für JPA im Package de.hausswolff.diplom.M zu speichern und im Package de.hausswolff.diplom.C die Controller (in dem Buch hießen diese Serviceklassen, also für Klasse User aus dem M Package wäre es dann halt UserService. Die Ausgabe in Form von normalen Servletts werde ich dann komplett in einem V Package bündeln. Was mich noch ein wenig beschäftigt ist, dass ich ja gerne nach dem REST Prinzip vorgehen möchte und also unter /user/3/inbox/5 den Eintrag von Benutzer mit der ID 3, den er erhalten hat (inbox) mit der ID 5 erhalten möchte. Ich nehme mal sehr stark an, dass es dafür eine Java Lib gibt. Habe aber auch noch nicht großartig gesucht. Ich werde - sobald ich die 3-Tabellen Lösung zum Laufen bekomme (siehe letzter Eintrag - war leider ein wenig spät/früh gestern/heuter ^^) - mal anfangen die neue Package Struktur als UML zu erstellen.

Subversion - how to do?

Ich wollte grad versuchen mein bisherigen Projekt auf den innoQ subversion server zu schieben. Allerdings hat es bisher noch nicht so funktioniert.

Weder
http://www.innoq.com/secure noch
https://www.innoq.com (nach dem wiki sollte das ja nach innoq.de weitergeleitet werden)
noch https://www.innoq.de/secure gingen.

Bei letzterem kam allerdings ein authentification error.
Vielleicht kann mir ja jemand einen Tipp geben.

October 25, 2007

cotodo lebt :-)

Collaboration ToDo List. Klingt irgendwie schön nach web 2.0.

Also das einchecken in Subversion hat auch recht schmerzlos funktioniert. Noch mal vielen Dank Stefan für die Tipp.
Noch mal in aller Klarheit:

https://www.innoq.com/svn/Sandbox/<user>

Momentan sitze ich mal wieder über meiner UML Skizze und versuche eine Art Service Struktur für meine Persitenten Objekte zu erstellen. So langsam finde ich gefallen daran, vor allem merkt man nach einer Weile, dass die Vorschläge aus dem Buch "Pro EJB 3. Java Persistence API" - (aPress) von Mike Keith und Merrick Schincariol ziemlich sinnvoll sind.


(Amazon Link)

Letztendlich geht es jetzt darum, die Funktionalität, die ich haben möchte soweit zu kapseln, dass sie sich mit dem vorgeschlagenen Design abbilden lässt.
Ich denke ich werde eh noch genug eigene Wege einschlagen - irgendwie liegt mir das im Blut :-).
Ich habe sogar ein Beispiel gefunden, wie man relative einfach DB Update von einer Programmversion auf die nächste mit JPA berwerkstelligen kann (Das war ein Punkt in unserer letzten Diplomandenrunde).

About October 2007

This page contains all entries posted to Philipps paper equivalent Blog in October 2007. They are listed from oldest to newest.

September 2007 is the previous archive.

November 2007 is the next archive.

Many more can be found on the main index page or by looking through the archives.

Powered by
Movable Type 3.31