Dienstag, Januar 12, 2010
Mein Dodge Charger
So, ich stelle hier jetzt mal ein paar Fotos von meinem '71 Dodge Charger rein, den ich mir letztes Jahr im Mai gekauft habe. Der Motor ist ein V8 mit 383 Kubikinch Hubraum, das sind so circa 6,3 Liter. Ich wollte im Winter noch einiges daran ändern, bin aber bisher noch nicht dazu gekommen.
Hier ein Bild auf dem Autozug, es war relativ tricky das Auto da draufzubekommen, weil er nur 5 cm unter der Maximallänge war und man bei der Einfahrt nicht in einem Zug um die Ecke gekommen ist. Aber mit dem Auto findet mal viele nette Helfer.
Hier dann schon wieder in Hamburg...
Und hier hatte die Zündspule keine Spannung mehr. Der ADAC-Mann hat dann die pragmatische Lösung gewählt und eine Freileitung von der Batterie zur Zündspule gelegt. Das funktionierte dann, hatte aber den Nebeneffekt, dass sich das Auto mit dem Zündschlüssel alleine nicht mehr ausschalten ließ. Also anhalten, Automatik auf P, Zündschlüssel abziehen, aussteigen, Motorhaube auf, Sicherung ziehen, Motorhaube zu. Beim Losfahren alles anderrum. Ist vor allem blöd wenn man nur mal tanken will...
Besonders empfehlen möchte ich das Blog von Chris, der gerade einen Charger restauriert und das ganz fantastisch in seinem Blog dokumentiert.
Hier ein Bild auf dem Autozug, es war relativ tricky das Auto da draufzubekommen, weil er nur 5 cm unter der Maximallänge war und man bei der Einfahrt nicht in einem Zug um die Ecke gekommen ist. Aber mit dem Auto findet mal viele nette Helfer.
Hier dann schon wieder in Hamburg...
Und hier hatte die Zündspule keine Spannung mehr. Der ADAC-Mann hat dann die pragmatische Lösung gewählt und eine Freileitung von der Batterie zur Zündspule gelegt. Das funktionierte dann, hatte aber den Nebeneffekt, dass sich das Auto mit dem Zündschlüssel alleine nicht mehr ausschalten ließ. Also anhalten, Automatik auf P, Zündschlüssel abziehen, aussteigen, Motorhaube auf, Sicherung ziehen, Motorhaube zu. Beim Losfahren alles anderrum. Ist vor allem blöd wenn man nur mal tanken will...
Besonders empfehlen möchte ich das Blog von Chris, der gerade einen Charger restauriert und das ganz fantastisch in seinem Blog dokumentiert.
Sonntag, Juli 27, 2008
Erste Gehversuche mit YouTube
So mal sehen, wie das mit YouTube klappt...Hier mein erstes Video:
Dienstag, Juli 15, 2008
HOW-TO organize a "Entspannte Barkassenparty"
So, ich möchte hier mal kurz zusammentragen, was man benötigt um eine entspannte Barkassenparty ohne viel Aufwand durchzuziehen. Und damit wir nächstes Jahr nicht wieder überlegen müssen wenn wir einkaufen gehen...
Rahmendaten der Party: Kleine Barkasse, zugelassen für 100 Leute, mehr als 60 ist allerdings echt zuviel - es gibt schließlich auch nur eine Toilette. Boarding: 18:30 Uhr. Fahrzeit von 19-22 Uhr (3 Stunden).
Hier die Liste mit Sachen, die man kaufen sollte.
- 2 mal 20 Liter Bier-Fässer (40 Liter) , wir haben selbstkühlende Fässer genommen, weil die da an Bord keine 220V Anlage haben und damit ansonsten nur die Dinger zum selberpumpen gehen. Geht auch - hatten wir letztes Jahr, aber das mit dem Selbstkühlenden ist schon eine feine Sache.
- 5 Kisten Bier (3 Becks-Gold, 1 Becks GreenLemon, 1 Becks Ice)
- 12 Flaschen Prosecco
- 6 Flaschen Wodka
- 6 Flaschen Erdbeerlimes
- 6 Flaschen Whiskey
- 1,5 Kisten Cola (1l)
- 6 l Orangensaft
- 0,5 Kisten Sprite/Wasser gemischt
- 1 Flasche Baileys
- 1 Flasche Jägermeister
- 1 Kiste Bionade
- 6 Flaschen Rotwein
- 5 mal 2 kg Eiswürfel
- eine Kühlbox für das Eis
- Becher groß für's Bier
- Becher klein für kurze
- 10 Packungen Ahoi-Browse für Wodka-Ahoi
- Müllbeutel
- Zewa-Haushaltstücher
- Korkenzieher nicht vergessen!
Im Endeffekt sind wir am Samstag vor der Party mal kurz einkaufen gefahren und am Montag hat Jerry - der zufällig gerade urlaub hatte - das Leergut zurück gebracht. Einziger Wehrmutstropfen war, dass mir meine Kontaklinsen ins Wasser gefallen sind. Also echt nicht viel Aufwand...Ach, schön war's...
Labels: Barkasse, Barkassenparty, Party
Sonntag, Dezember 30, 2007
Hibernate, Spring, Transaktionen auf Service-Ebene
Anwendungen, die Hibernate zur Persistierung benutzen, treffen gelegentlich auf das Problem einer org.hibernate.LazyInitializationException. Diese Exception tritt auf, wenn eine Instanz aus der Datenbank geholt wird, die Referenzen auf andere persistente Instanzen besitzt und diese Referenzen mit lazy="true" im hibernate-mapping gekennzeichnet ist. Dieses lazy="true" bedeutet, dass die abhängigen Instanzen bei Bedarf - und damit beim ersten Zugriff darauf - nachgeladen werden. Hibernate benutzt dazu Proxies, die beim ersten Zugriff auf die Referenz diese aus der Datenbank nachladen und diese gegen sich selber austauschen. Die LazyInitializationException tritt nun auf wenn man eine Instanz mit uninitialisierten (lazy) Referenzen besitzt und versucht auf diese Referenzen zuzugreifen und bedauerlicherweise vorher die Session geschlossen hat. Dann weiss Hibernate nicht wie es die Referenzen holen soll und dann knallts.
Hibernate Sessions. Wenn man direkt mit Hibernate rummacht, dann muss man sich mehr oder weniger selbst darum kümmern wann die Session geöffnet und geschlossen wird. Dazu gibt es so einige Ansätze wie man das schlauerweise macht, z.B. für Webanwendungen den OpenSessionInViewFilter. Diese Ansätze führen dazu, dass immer eine geöffnete Session vorhanden ist. Das hilft allerdings auch nicht, wenn ein persistentes Objekt mit lazy Referenzen in die HttpSession gekippt wird und in einem späteren Request/Response-Zyklus versucht wird die lazy Referenzen aufzulösen. Hier hätte das persistente Objekt mit merge() oder update() erstmal wieder an die aktuelle Session gebunden werden müssen.
Transaktionen. Eine gute Anwendung sollte Transaktionen benutzen und zwar Transaktionen auf Serviceebene. Viele Beispiele zur Verwendung von Spring und Hibernate zeigen wie Transaktionen auf Dao-Ebene funktionieren. Aber ist das sinnvoll ? Ich denke nein. Exceptions auf Dao-Ebene haben entweder technischen Hintergrund, wie verlorene Datenbankverbindungen, oder Verletzung von Constraints wie NOT NULL oder referenzieller Integrität. Außerdem sind die Aktionen in Daos doch eher simpel INSERT, UPDATE, DELETE, ein paar mehr oder weniger kompexe SELECTs. Alles nicht wirklich spannend für Transaktionen. Betrachtet man hingegen den Service-Layer, der per Definition die Geschäftlogik beinhaltet, dann findet man hier oft Methoden, die sich aus verschiedenen Daos bedienen und ihre Ergebnisse über ein oder mehrere Daos in die Datenbank fliessen lassen. Die Operationen sind deutlich komplexer - eben Businesslogik. Hier kann schon viel eher mal was schief gehen und zwar mehr Ausnahmen im Sinne der Businesslogik - deshalb sollte zu jedem Service auch eine passende Exception existieren und bei Bedarf geworfen werden. Ausnahmen, die die bisherigen Änderungen an der Datenbank wieder zurücknehmen sollen und dann an den Aufrufer weitergegeben werden. Hier sind die Transaktionen wirklich sinnvoll. Praktischerweise funktioniert das automatisch, wenn die Service-Exception von RuntimeException erbt. Ein hübscher Vorteil von Transaktionen auf Service-Ebene ist, dass hier die Hibernate-Session die Gleiche ist damit das verwenden von lazy Referenzen im Service-Layer kein Problem darstellt, weil alle "lazy"-Referenzen transparent aufgelöst werden.
Entkopplung auf Service-Ebene. Die "Kunden" eines Service-Layers sollen die Rückgabewerte ohne Einschränkungen verwenden können. Da die Session aber mit Ende der Transaktion ebenfalls geschlossen wird, ist die Verwendung von "lazy"-Referenzen jenseits des Service-Layers nicht mehr möglich. Das bedeutet, dass man aus Sicht des Service Layers entweder sehr genau wissen muss, welche der Lazy-Referenzen vom Kunden verwendet werden um diese gezielt zu initialisieren oder eben alle potentiell nutzbaren Referenzen zu initalisieren. Für die selektive Initialisierung kann man Frameworks benutzen, z.B. ServiceDataObject Framework. Das hat allerdings den Nachteil, das der Kunde sich Gedanken über die Verwendungstiefe machen muss. Gelegentlich ist der Kunde aber auch nur ein weiterer Layer, der dann diese Gedanken auch seinem Kunden zumuten muss, usw. Die andere Alternative ist die voll Initialisiering der Rückgabewerte. Je nachdem wie exzessiv das Hibernate-Mapping betrieben wurde, kann es passieren, dass man nach einem einzigen Aufruf die ganze Datenbank als Objektbaum im Hauptspeicher hat. Dennoch ist es aus Sicht des Kunden optimal, weil er innerhalb der Objektstruktur problemlos navigieren kann.
Meine Best Practices und Regeln. Ich verwende in meinen Projekten Transaktion auf Service-Ebene und gebe aus dieser nur voll initialisierte Objektbäume zurück. Ich verwende für die Transaktionen und die Initialisierung von Rückgabewerten Spring-AOP. Diese Vorgehensweise funktioniert allerdings nur, wenn für die Architektur des Service-Layers und für das Hibernate-Mapping einige Regeln beachtet werden.
Hibernate Sessions. Wenn man direkt mit Hibernate rummacht, dann muss man sich mehr oder weniger selbst darum kümmern wann die Session geöffnet und geschlossen wird. Dazu gibt es so einige Ansätze wie man das schlauerweise macht, z.B. für Webanwendungen den OpenSessionInViewFilter. Diese Ansätze führen dazu, dass immer eine geöffnete Session vorhanden ist. Das hilft allerdings auch nicht, wenn ein persistentes Objekt mit lazy Referenzen in die HttpSession gekippt wird und in einem späteren Request/Response-Zyklus versucht wird die lazy Referenzen aufzulösen. Hier hätte das persistente Objekt mit merge() oder update() erstmal wieder an die aktuelle Session gebunden werden müssen.
Transaktionen. Eine gute Anwendung sollte Transaktionen benutzen und zwar Transaktionen auf Serviceebene. Viele Beispiele zur Verwendung von Spring und Hibernate zeigen wie Transaktionen auf Dao-Ebene funktionieren. Aber ist das sinnvoll ? Ich denke nein. Exceptions auf Dao-Ebene haben entweder technischen Hintergrund, wie verlorene Datenbankverbindungen, oder Verletzung von Constraints wie NOT NULL oder referenzieller Integrität. Außerdem sind die Aktionen in Daos doch eher simpel INSERT, UPDATE, DELETE, ein paar mehr oder weniger kompexe SELECTs. Alles nicht wirklich spannend für Transaktionen. Betrachtet man hingegen den Service-Layer, der per Definition die Geschäftlogik beinhaltet, dann findet man hier oft Methoden, die sich aus verschiedenen Daos bedienen und ihre Ergebnisse über ein oder mehrere Daos in die Datenbank fliessen lassen. Die Operationen sind deutlich komplexer - eben Businesslogik. Hier kann schon viel eher mal was schief gehen und zwar mehr Ausnahmen im Sinne der Businesslogik - deshalb sollte zu jedem Service auch eine passende Exception existieren und bei Bedarf geworfen werden. Ausnahmen, die die bisherigen Änderungen an der Datenbank wieder zurücknehmen sollen und dann an den Aufrufer weitergegeben werden. Hier sind die Transaktionen wirklich sinnvoll. Praktischerweise funktioniert das automatisch, wenn die Service-Exception von RuntimeException erbt. Ein hübscher Vorteil von Transaktionen auf Service-Ebene ist, dass hier die Hibernate-Session die Gleiche ist damit das verwenden von lazy Referenzen im Service-Layer kein Problem darstellt, weil alle "lazy"-Referenzen transparent aufgelöst werden.
Entkopplung auf Service-Ebene. Die "Kunden" eines Service-Layers sollen die Rückgabewerte ohne Einschränkungen verwenden können. Da die Session aber mit Ende der Transaktion ebenfalls geschlossen wird, ist die Verwendung von "lazy"-Referenzen jenseits des Service-Layers nicht mehr möglich. Das bedeutet, dass man aus Sicht des Service Layers entweder sehr genau wissen muss, welche der Lazy-Referenzen vom Kunden verwendet werden um diese gezielt zu initialisieren oder eben alle potentiell nutzbaren Referenzen zu initalisieren. Für die selektive Initialisierung kann man Frameworks benutzen, z.B. ServiceDataObject Framework. Das hat allerdings den Nachteil, das der Kunde sich Gedanken über die Verwendungstiefe machen muss. Gelegentlich ist der Kunde aber auch nur ein weiterer Layer, der dann diese Gedanken auch seinem Kunden zumuten muss, usw. Die andere Alternative ist die voll Initialisiering der Rückgabewerte. Je nachdem wie exzessiv das Hibernate-Mapping betrieben wurde, kann es passieren, dass man nach einem einzigen Aufruf die ganze Datenbank als Objektbaum im Hauptspeicher hat. Dennoch ist es aus Sicht des Kunden optimal, weil er innerhalb der Objektstruktur problemlos navigieren kann.
Meine Best Practices und Regeln. Ich verwende in meinen Projekten Transaktion auf Service-Ebene und gebe aus dieser nur voll initialisierte Objektbäume zurück. Ich verwende für die Transaktionen und die Initialisierung von Rückgabewerten Spring-AOP. Diese Vorgehensweise funktioniert allerdings nur, wenn für die Architektur des Service-Layers und für das Hibernate-Mapping einige Regeln beachtet werden.
- Fortpflanzung Begrenzen. Es muss immer beachtet werden, das ein Objekt, dass über den Service-Layer bezogen wird alle referenzierten Objekt einschließt. Das bedeutet, dass verschachtelte und inverse 1:n Beziehungen keine gute Idee sind, weil die Initialisierungsroutine alles Initialisiert was erreichbar ist - und das ist in diesem Fall alles. Man muss also beim Mapping Schranken vorsehen die die Fortpflanzung in zu große Objektstrukturen verhindern.
- Fetter Service-Layer. Der Service-Layer an sich wird tendentiell mehr Methoden enthalten, weil nur eine persistente Objektinstanz zurückgegeben werden sollte, wenn diese mit ihren Abhängigkeiten auch wirklich benötigt wird. Benötigt man zum Beispiel eine Liste mit Namen von Produkten, dann ist der Rückgabewert ein String[] und nicht eine List
. Innerhalb der Service-Methode kann über die List iteriert werden um das String-Array aufzubauen, aber innerhalb des Service-Layers können die Abhängigkeiten von der Product-Instanzen "lazy" bleiben. Der Service-Layer wird durch diese Art der Verwendung etwas aufgebläht, weil es für jeden kram eine extra Methode gibt, aber das ist ein kleiner Preis für eine problemlose Verwendung.
Labels: Best Practice, Hibernate, Spring, Transaktionen
Dienstag, Juli 17, 2007
Dynamic JSCookMenue to the same outcome
The problem occurs on a JSCookMenue, if you wish to create the NavigationItems dynamically from a backing bean and some of the menu entries should be result in the same outcome. Typically you want to distinct the selected menu entries on the selected page (target of the outcome), but this is impossible, because you can't transfer the information of the selected entry.
In case of static NavigationItems you can use an ActionListener to transfer this information into a backing bean, where you can read this information on the next page. But in case of dynamically created menuitems you havn't the possiblility to add an ActionListener , because the NavigationItem isn't a Component. Only the JSCookMenu is.
So that is the problem. The solution I found is dirty, but it works. Better approaches are welcome !
The only thing you can add to a NavigationItem is the action attribute. So I extend the action attribute from "report" to something like "report_report1" and "report_report2". Then I wrote a custom NavigationHandler that hijacks outcomes which starts with "report_" and the only Job of this NavigationHandler is to change the outcome to "report" and put the other part of the term ("report1" or "report2") into a sessionbased backingbean.
This approach is weak, because it adds a new meaning to the naming of action outcomes, but currently I doesn't found anything else working for me.
In case of static NavigationItems you can use an ActionListener to transfer this information into a backing bean, where you can read this information on the next page. But in case of dynamically created menuitems you havn't the possiblility to add an ActionListener , because the NavigationItem isn't a Component. Only the JSCookMenu is.
So that is the problem. The solution I found is dirty, but it works. Better approaches are welcome !
The only thing you can add to a NavigationItem is the action attribute. So I extend the action attribute from "report" to something like "report_report1" and "report_report2". Then I wrote a custom NavigationHandler that hijacks outcomes which starts with "report_" and the only Job of this NavigationHandler is to change the outcome to "report" and put the other part of the term ("report1" or "report2") into a sessionbased backingbean.
This approach is weak, because it adds a new meaning to the naming of action outcomes, but currently I doesn't found anything else working for me.
Labels: Dynamic Items, JSCookMenue, JSF
Barkassenfahrt
Am Wochenende eine kleine Party mit der WG organisiert. Dazu eine Barkasse gemietet, etwas Getränke eingekauft und allen Bescheid gesagt die Bock haben.
Hier die Fotos:
von Björn
Hier die Fotos:
von Björn
Dienstag, März 13, 2007
Vista ist schon toll...
Dienstag, Februar 06, 2007
Ich bin ein EC-Karten Skimming Opfer !
Ich war Samstagnacht mit zu wenig Bargeld unterwegs. Dann ich hin zum Geldautomaten, Karte rein, PIN eingegeben - Kurze Meldung, dass meine Karte eingezogen werden musste. Wie schön. Nicht nur, dass der Rest der Leute in der Automatenhalle der Bremer Sparkasse mich für einen total armen Schlucker gehalten haben, dem sie gerade so ziemlich alles unter dem Arsch wegpfänden würden - nein, ich war zudem auch noch weiterhin ohne Bargeld unterwegs.
Naja, ich dann gestern bei der Filiale der Bremer Sparkasse angerufen um mal zu erfahren was da nun los war. Bin in der Zentrale gelandet, die mir versprach das Thema an die Filiale weiterzugeben. Auf den Rückruf warte ich vergeblich. Diesen Service bekommt man auch nur in Deutschland.
Aber es kommt noch besser. Gestern Abend, so um 19 Uhr ruft jemand von der Hamnburger Sparkasse an. Blöderweise war ich da gerade beim Sport - aber zumindest arbeitet da mal jemand länger als 16 Uhr. Ich heute morgen also Zurückgerufen - ich mache sowas ja gelegentlich - und ein nettes Gespräch mit dem Herrn von der Haspa gehabt. Dabei hat er mir erzählt, dass es eine zentrale Stelle gibt, die Auffälligkeiten bei EC-Karten-Nutzungen registriert um dublizierte Karten zu erkennen. So zum Beispiel am gleichen Tag in London und Amsterdam Geld aus Automaten ziehen. Diese Stelle hat meine Karte als "auffällig" ausgeworfen und das Standardverfahren ist dann eben diese Karte zu sperren. Das fand ich okay, schließlich will ich der Einzige sein, der von meinem Konto Geld abhebt. Dann hat er sich tausendmal entschuldigt, weil der Anruf so spät kam - was ich zuerst gar nicht begriffen habe. Doch dann kam er damit um die Ecke, dass die Karte ja bereits am 31.01.2007 gesperrt worden ist. Also 7 Tage vor dem Anruf - jetzt hab' ich dann auch die Entschuldigung verstanden. Unklar bleibt mir noch wie ich am Samstag im Supermarkt noch mit EC-Karte/PIN bezahlen konnte, wenn die da doch eigentlich schon gesperrt gewesen sein sollte - dazu fiel dem Haspa-Mitarbeiter auch nichts ein. Naja, was'n Glück dass ich bereits seit längerem Kunde bei der Comdirekt bin - eigentlich ja nur wegen der 3.3 % auf Tagesgeld - und da auch eine EC-Karte bekommen habe die ich dann jetzt mal nutzen werde. Mal sehen, ob ich mir die neue Geheimnummer der Haspa-EC-Karte nochmal merken möchte.
Naja, ich dann gestern bei der Filiale der Bremer Sparkasse angerufen um mal zu erfahren was da nun los war. Bin in der Zentrale gelandet, die mir versprach das Thema an die Filiale weiterzugeben. Auf den Rückruf warte ich vergeblich. Diesen Service bekommt man auch nur in Deutschland.
Aber es kommt noch besser. Gestern Abend, so um 19 Uhr ruft jemand von der Hamnburger Sparkasse an. Blöderweise war ich da gerade beim Sport - aber zumindest arbeitet da mal jemand länger als 16 Uhr. Ich heute morgen also Zurückgerufen - ich mache sowas ja gelegentlich - und ein nettes Gespräch mit dem Herrn von der Haspa gehabt. Dabei hat er mir erzählt, dass es eine zentrale Stelle gibt, die Auffälligkeiten bei EC-Karten-Nutzungen registriert um dublizierte Karten zu erkennen. So zum Beispiel am gleichen Tag in London und Amsterdam Geld aus Automaten ziehen. Diese Stelle hat meine Karte als "auffällig" ausgeworfen und das Standardverfahren ist dann eben diese Karte zu sperren. Das fand ich okay, schließlich will ich der Einzige sein, der von meinem Konto Geld abhebt. Dann hat er sich tausendmal entschuldigt, weil der Anruf so spät kam - was ich zuerst gar nicht begriffen habe. Doch dann kam er damit um die Ecke, dass die Karte ja bereits am 31.01.2007 gesperrt worden ist. Also 7 Tage vor dem Anruf - jetzt hab' ich dann auch die Entschuldigung verstanden. Unklar bleibt mir noch wie ich am Samstag im Supermarkt noch mit EC-Karte/PIN bezahlen konnte, wenn die da doch eigentlich schon gesperrt gewesen sein sollte - dazu fiel dem Haspa-Mitarbeiter auch nichts ein. Naja, was'n Glück dass ich bereits seit längerem Kunde bei der Comdirekt bin - eigentlich ja nur wegen der 3.3 % auf Tagesgeld - und da auch eine EC-Karte bekommen habe die ich dann jetzt mal nutzen werde. Mal sehen, ob ich mir die neue Geheimnummer der Haspa-EC-Karte nochmal merken möchte.
Labels: Banken, EC-Karten-Skimming, Servicewüste