Archiv für Kategorie Arbeit

Große Trabbi-Roadtour

Ich hatte heute am letzten Freitag die einmalige Gelegenheit im Rahmen eines Incentives, das mein Arbeitgeber für die erfolgreiche Fortführung des startothek-Projekts ausgerichtet hat, eine Roadtour durch das Münsterland zu machen und zwar mit einem Trabant 601. Es kam hierbei auf das Anfahren verschiedener Stationen und auf das Lösen von Aufgaben und einem Quiz an sowie auf das Verfahren von möglichst wenigen Kilometern.

In sechs Teams zu je zwei oder drei Mitfahrern in je einem Trabant waren einzelne Etappen abzufahren und die in einem Roadbook aufgeführten Aufgaben zu erledigen. Aber zunächst stand eine Einweisung für die Fahrer an, denn ein Trabbi ist ein automobiler Sonderfall. So gibt es z.B. keine Tankanzeige, der geneigte Fahrer muss einen Plastikstab in den Tank halten um abschätzen zu können, wie weit er noch fahren kann.

Die größte Hürde beim Umstieg ist aber die Lenkradschaltung. Mit einem Hebel kann man vier Gänge durchschalten: der erste Gang ist unten, in der Mitte der Leerlauf und oben der zweite. Danach muss man den Hebel herausziehen und hat denn unten den dritten und oben den vierten. Den Rückwärtsgang erreicht man durch Reindrücken des Hebels. Geradezu zerbrechlich nimmt sich der Blinkerhebel aus, bei dem man jedesmal Angst haben muss, dass man ihn nach dem Blinken in der Hand hat.

Das Sandsteinmuseum in Havixbeck Nach anfänglichen Schwierigkeiten ging es dann auf die Straße. Erstes Ziel war das Sandsteinmuseum in Havixbeck. Dort war die Frage zu klären, wie die Sagengestalten genannt wurden, von denen man glaubte, dass sie im Sandstein leben würden. Nachdem wir rausbekommen hatten, dass sich diese Teitekerlken schimpfen, erhielten wir noch eine Münsterland-Erlebniskarte zwecks Navigation und machten uns wieder auf den Weg. Der Trabant hat einen Benzinhahn im Innenraum, den man schließen sollte, wenn man den Wagen länger stehen lässt. Dumm nur, wenn man ihn – wie wir – vergisst wieder zu öffnen, wenn man weiterfährt. Wir kamen etwa 800 Meter weit, was reichte, um auf eine Kreuzung zu rollen. Aber mit einem Trabbi kann man sich einiges erlauben, ohne dass jemand hupt. Anscheinend haben alle Mitleid.

Zweite Anlaufstelle auf der Tour war die St. Johannes Kirche in Altenberge. Dort war eine geografische Maßeinheit gefragt und ihre Bedeutung. Auf der Seite der Kirche findet sich eine Plakette mit der Inschrift 108 NN, die besagt, dass die Kirche eben 108 Meter über Normalnull liegt. Nach dieser Aufgabe ging es wieder ins Auto und weiter nach Burgsteinfurt.

Das ewige Rätsel, wo jetzt der Unterschied zwischen Steinfurt und Burgsteinfurt liegt, konnte ich auch dieses Mal nicht lösen, ich vermute aber immer noch stark, dass es letztendlich zwei Namen für den gleichen Ort sind. OK, mittlerweile bin ich schlauer: 1975 wurden Burgsteinfurt und Borghorst zusammengelegt zu Steinfurt. Im dortigen Café gab es dann Kaffee und Kuchen. Ã?hnlich wie in der DDR gab es nicht viel auszusuchen, die Wahl des Kuchens orientierte eher an der Verfügbarkeit als am persönlichen Geschmack. Während des Zwischenstopps versuchten wir uns dann am DDR-Quiz, dass im Roadbook aufgeführt war und auch zur Bewertung herangezogen wurde.

Das Holtwicker Ei Nach der Pause ging es über Land weiter zum Holtwicker Ei. Es handelt sich dabei um einen großen Findling, um den man einen kleinen Park herum gebaut hat. Dumm nur dass man das Ding fast nicht findet, wenn man nicht weiß, wo genau es ist. Man fährt dort leicht dran vorbei. Im dortigen Park nahmen wir an einem Ost-/Westproduktvergleich teil, bei dem es galt, zwei Nougatcremes und zwei Kekssorten mit verbundenen Augen in Ost und West zu klassifizieren, was meinem Mitfahrer Markus und mir auch gelang. Lediglich bei der Unterscheidung von Liedtexten der Puhdys und der Münchner Freiheit mussten wir dann passen, die Texte sind bei beiden etwa gleich schnulzig.

Der Longinusturm Wieder unterwegs war das nächste Ziel der Longinusturm nahe Nottuln. Die um Roadbook abgedruckten Orientierungskarten mit der offiziellen Routenempfehlung erschienen uns als Umweg, weshalb wir von Rosendahl (dort liegt das Holtwicker Ei) über Billerbeck nach Baumberge bzw. Nottuln fuhren. Diese Entscheidung sparte uns einige Kilometer. Als wir am Turm ankamen wurde dort eine für den Abend geplante Festivität samt Feuerwerk und WDR-Liveübertragung vorbereitet. Hintergrund des ganzen: Billerbeck, Nottuln und Havixbeck sind Preisträger des Ab in die Mitte!-Wettbewerbs des Landes NRW, einem Programm zur Förderung von Stadt- und Kommunalmarketing. Am Longinusturm würde um 20 Uhr die Auftaktveranstaltung zu den Feierlichkeiten stattfinden, die sich die nächsten Monate hinziehen würden.

Was es nicht alles gibt: der größte und schwerste Standaschenbecher der Welt Es galt nun die Frage zu klären, wie hoch der Turm eigentlich insgesamt ist. Der Baumberg ist mit 187,61 Metern über NN die höchste Erhebung des Münsterlandes (was ich als gebürtiger Wuppertaler eher peinlich finde), der Turm selber hat 32 Meter Höhe zuzüglich etwaiger Antennen. Die Aussicht vom Turm ist ganz nett aber nicht wirklich überragend, vor allem auch weil es eigentlich nichts Sehenswertes in der Umgebung gibt. Eine witzige Kleinigkeit steht vor dem Turm: der größte und schwerste Standaschenbecher der Welt, der sogar im Guinessbuch der Rekorde steht.

Der Longinusturm war die letzte Station im Roadbook und wir fuhren von dort aus wieder zurück nach Nienberge. Insgesamt hatten wir an diesem Tag 113 Kilometer im Trabant zurückgelegt, über 10 Kilometer weniger als jedes andere Team. Letzten Endes war diese Tatsache für unseren Gesamtsieg ausschlaggebend. Der Abend klang dann mit einem gemütlichen Essen samt Preisverleihung am Hafen aus.

Die Tour ist vorbei, alle Teilnehmer sind zurÃ?¼ck.Von dieser Stelle nochmals vielen Dank an die Organistoren von der Event & Touring AG sowie Petra und alle anderen Mitfahrer! Es hat wirklich Spaß gemacht! Und ein großes Sorry an den LKW-Fahrer auf der Landstraße zwischen Steinfurt und Rosendahl: wir haben wirklich gedacht, wir kämen mit dem Trabbi schneller weg…

, ,

1 Kommentar

Seltsame Begegnungen oder der Tag an dem ich zum Ausbilder wurde

Ich kann mich noch erinnern, wie ich zu Anfang meiner Ausbildung zum Ausbilder von einem Dozenten gefragt wurde, welchen Ausbildungsberuf ich erlernt hätte. Als ich erwiderte, ich hätte keine Ausbildung im IHK-Sinne sondern ein Diplom in Informatik von der FH Dortmund, bekam ich zu hören “Aber sie brauchen doch eine fachliche Eignung um Ausbilder zu werden”.

Aber alle Unwägbarkeiten sind durchstanden, heute habe ich die mündliche Prüfung zum Ausbilder bestanden und bin damit berechtigt, Auszubildende auszubilden. Nicht dass man einen solchen Ausbilderschein derzeit bräuchte, evtl. wird man ihn nach Verlängerung des Aubildungspakts auch bis 2010 erstmal nicht brauchen, aber was man hat, das hat man.

Mit der mündlichen Prüfung kam dann auch die erste seltsame Begegnung: das Prüfungstrio der IHK. Es hat eine Weile gebraucht, bis ich verstanden hatte, dass man gar nicht mit mir diskutieren wollte, auch wenn die Fragen den Anschein machten, sondern lediglich bestimmte Schlüsselwörter (z.B. Handlungskompetenz, Ausbildungsordnung, Schlüsselqualifikationen, etc.) hören will und dass man bei seinem Standpunkt bleibt. Da war ich nur bedingt drauf vorbereitet, denn wer rechnet schon mit Fragen wie “Glauben Sie, dass Sie Auszubildende des ersten Lehrjahrs so ohne Vorbereitung auf eine Overheadfolie schreiben lassen können?” Was soll man auf so eine Frage antworten? Aber Ende gut, alles gut.

Die nächste interessante Begegnung hatte ich dann auf dem Weg zum Sport. Auf der B54 kam mir mein Auto entgegen, ebenfalls ein blauer Octavia RS Kombi. Skoda gibt als Absatzziel für den RS 1100 Einheiten pro Jahr deutschlandweit an, also ist die Wahrscheinlichkeit, den baugleichen RS zu treffen doch recht gering.

Die dritte Begegnung hatte ich dann beim Sport. Vom Studio aus kann man auf den Hafenplatz. Vom Kraftwerk aus führt eine Eisenbahnstrecke quer über den Albersloher Weg und hinter dem Kino lang. Jetzt bin ich nicht häufig dort in der Gegend, aber ich hätte behauptet, dass dort nie ein Zug fährt. Falsch gedacht, heute fuhr dort tatsächlich eine einzelne Diesellok, begleitet von einem Arbeiter, der die Schrankenanlage auf dem Albersloher Weg bediente. Für viele Kinogänger und Autofahrer dürfte das auch das erste Mal gewesen sein.

Achja, und nochwas: Joost ist verdammt instabil und intuitiv bedienbar sieht auch anders aus. Aber das Angebot an Inhalten ist jetzt schon recht gut.

, ,

Keine Kommentare

Schon wieder Berlin, diesmal gutes Wetter

Am vergangenen Donnerstag (19.4.) ging es wieder auf Dienstreise nach Berlin. Diesmal hatten wir einen Termin, der erst mittags anfing, ich konnte also “ausschlafen”, der Zug ging erst um 8:34 Uhr. Zu unser aller Überraschung herrschte in Berlin gutes Wetter, also zu Abwechslung mal kein schwerer Orkan oder sintflutartiger Regen. Nach dem Termin bei der Kreditanstalt für Wiederaufbau blieb uns noch etwas Zeit, die Stadt endlich mal aus der Nähe zu betrachten. Ich war jetzt schon mindestens sechs mal in Berlin – immer dienstlich – und habe bisher weder die Siegessäule noch das Brandenburger Tor aus der Nähe gesehen. Am Gendarmenmarkt war viel Polizei präsent, man erwartete die G8-Umweltminister zu einem Treffen. Ich hab mal recherchiert, da niemandem die Namen der restlichen sieben nicht-deutschen Umweltminister einfallen wollten:

Interessant ist, dass die USA nicht über ein Umweltministerium im deutschen Sinne zu verfügen scheinen, Mike Leavitt ist eher Gesundheitsminister als Umweltminister. Naja, wen wunderts.

, , ,

Keine Kommentare

Realistische Betrachung: Administratoren vs. Entwickler

Im ONJava.com-Blog von O’Reilly wurde heute ein interessanter Artikel Timothy O’Brien veröffentlicht, der sich mit den häufig auftretenden Konflikten zwischen Entwicklern und Administratoren beschäftigt. Er nennt sich Java’s “Operations” Problems und bietet eine sehr interessante Betrachtungsweise eines typischen Konflikts, den vermutlich jeder Entwickler in größeren Unternehmen schon einmal erlebt hat: der Entwickler möchte etwas, der Administrator möchte genau das nicht oder auch umgekehrt. Dies führt meist zu größeren Konflikten, die mehr einem Glaubenskrieg ähneln als einer sachlichen Diskussion.

Der Artikel handelt in diesem Fall speziell von Java, dass durch seine Abstraktion von den eigentlichen Systemgrundlagen eine zusätzliche Hürde mit einbringt, die vorgestellten Thesen und Lösungsansätze sind allerdings allgemeingültig.
O’Brien sieht den Grund für die Konflikte in einer zu starren Abgrenzung zwischen den beiden Personengruppen, deren Tätigkeit thematisch überlappt, deren Zuständigkeiten aber hart getrennt sind. Er skizziert eine ideale Verfahrensweise und und stellt einen zweistufigen Plan vor, wie man die Reibung zwischen Administration und Entwicklung verringert.

The Short-term Solution: Hold Hands and Sing a Song

If your organization has friction between Operations and Development, a quick short-term fix is to nominate one person from each team to serve as a liaison to the other group.

Diesen Schritt haben wir in unserer Firma bereits vollzogen und es hat sich als sehr gut heraus gestellt, eine direkte Schnittstelle zur anderen Abteilung zu haben. Probleme aber auch Anforderungen sind so viel einfacher zu klären.

The Long-term Solution: Stop Developing Applications, Stop Administering Systems

â?¦do away with System Administrators and Application Developers. No, really, I mean that.

Der Ausschnitt selber klingt recht drastisch, er beschreibt aber eine thematische Annäherung von Administratoren und Entwicklern und den Wandel der klassischen Rollen im Verlauf der Zeit und im Zuge der technischen Entwicklung.

Insgesamt ein sehr lesenswerter Artikel, den ich jedem Administrator und jedem Entwickler nur empfehlen kann.

Keine Kommentare

JPA: Bidirektionale OneToMany/ManyToOne Beziehungen

Dieser Beitrag soll in erster Linie für mich als Gedächtnisstütze dienen. Als Nachwirkung der Schulung beschäftige ich mich nicht nur mit Enterprise Java Beans (EJB) sondern auch mit der Java Persistence API (JPA), dem "neuen" Persistenzstandard, der im gleichen Prozess wie EJB entworfen wurde. Im Entwicklerforum von java.net findet sich ein passender Satz zu dem Thema, den jemand als Antwort bekam, der sich darüber beklagt, dass JPA so unvorhersehbar arbeiten würde:

I doubt that it's a matter of it being "unpredictable" so much as it is getting over the learning curve.

Genau in dieser Lernkurve stecke ich auch derzeit noch und erlerne JPA gerade im Eigenstudium. Für erfahrene Entwickler ist dieser Beitrag daher nicht gedacht.

Das Problem

Es existieren zwei Entitäten, Benutzer und Gruppe. Jeder Benutzer kann einer Gruppe angehören, folglich können zu einer Gruppe mehrere Benutzer gehören. Beide Entitäten sind wie folgt definiert:

JAVA:
  1. public class Benutzer
  2. {
  3.     private String _name;
  4.     private String _vorname;
  5.     private String _benutzername;
  6.     private String _email;
  7.     private int _id;
  8.     private Gruppe _gruppe;
  9.  
  10.     /*
  11.      * Es folgen die ganze Getter und Setter fuer die
  12.      * obigen Eigenschaften.
  13.      * [...]
  14.      */
  15.    
  16.     @ManyToOne
  17.     public Gruppe getGruppe()
  18.     {
  19.         return _gruppe;
  20.     }
  21.  
  22.     public void setGruppe(final Gruppe gruppe)
  23.     {
  24.         _gruppe = gruppe;
  25.     }
  26. }

JAVA:
  1. public class Gruppe
  2. {
  3.     private int _id;
  4.     private String _name;
  5.     private String _beschreibung;
  6.     private Set<Benutzer> _benutzer = new HashSet<Benutzer>();
  7.            
  8.     /*
  9.      * Es folgen die ganze Getter und Setter fuer die
  10.      * obigen Eigenschaften.
  11.      * [...]
  12.      */            
  13.            
  14.     @OneToMany(mappedBy = "gruppe")
  15.     public Set<Benutzer> getBenutzer()
  16.     {
  17.         return _benutzer;
  18.     }
  19.  
  20.     public void setBenutzer(final Set<Benutzer> benutzer)
  21.     {
  22.         _benutzer = benutzer;
  23.     }
  24. }

Ein kleines Programm geht jetzt her und erzeugt drei Benutzer und zwei Gruppen. Zwei der Benutzer werden der ersten Gruppe zugewiesen, der dritte der anderen Gruppe.

JAVA:
  1. EntityManager em = createEntityManager();
  2.  
  3.         final Gruppe g1 = createGruppe("Demokraten", "Die Partei der Demokraten");
  4.         final Gruppe g2 = createGruppe("Republikaner", "Die Partei der Republikaner");
  5.  
  6.         em.persist(g1);
  7.         em.persist(g2);
  8.        
  9.         final Benutzer b1 = createBenutzer("Obama", "Barack", "bobama", "obama@senate.gov");
  10.         final Benutzer b2 = createBenutzer("McCain", "John", "jmccain", "mccain@senate.gov");
  11.         final Benutzer b3 = createBenutzer("Clinton", "Hillary", "hclinton", "clinton@senate.gov");
  12.  
  13.         b1.setGruppe(g1);
  14.         b2.setGruppe(g2);
  15.         b3.setGruppe(g1);
  16.  
  17.         em.persist(b1);
  18.         em.persist(b2);
  19.         em.persist(b3);

Danach geht das Programm her und lädt die Datensätze wieder aus der Datenbank und gibt sie und ihre Beziehungen aus.

JAVA:
  1. final List result = em.createQuery("SELECT b FROM Benutzer b ORDER BY b.name").getResultList();
  2.        
  3.         for (final Object b : result)
  4.         {
  5.             if (b instanceof Benutzer)
  6.             {
  7.                 final Benutzer benutzer = (Benutzer) b;
  8.                 LOG.info(benutzer);
  9.                 LOG.info("\t+--> " + benutzer.getGruppe());
  10.             }
  11.         }
  12.  
  13.         final List result2 = em.createQuery("SELECT g FROM Gruppe g").getResultList();
  14.        
  15.         for (final Object o : result2)
  16.         {
  17.             if (o instanceof Gruppe)
  18.             {
  19.                 final Gruppe g = (Gruppe) o;
  20.                 LOG.info(g);
  21.                 LOG.info("Benutzerzahl: " + g.getBenutzer().size());
  22.  
  23.                 for(final Benutzer b : g.getBenutzer())
  24.                 {
  25.                     LOG.info("\t+--> " + b);
  26.                 }
  27.             }
  28.         }

Es entsteht folgende Ausgabe:

CODE:
  1. JPAClient.showDemo()@107: Benutzer [2902]: Clinton, Hillary (hclinton, clinton@senate.gov)
  2. JPAClient.showDemo()@108:   +--> Gruppe [2800]: Demokraten (Die Partei der Demokraten)
  3. JPAClient.showDemo()@107: Benutzer [2901]: McCain, John (jmccain, mccain@senate.gov)
  4. JPAClient.showDemo()@108:   +--> Gruppe [2801]: Republikaner (Die Partei der Republikaner)
  5. JPAClient.showDemo()@107: Benutzer [2900]: Obama, Barack (bobama, obama@senate.gov)
  6. JPAClient.showDemo()@108:   +--> Gruppe [2800]: Demokraten (Die Partei der Demokraten)
  7. JPAClient.showDemo()@120: Gruppe [2800]: Demokraten (Die Partei der Demokraten)
  8. JPAClient.showDemo()@121: Benutzerzahl: 0
  9. JPAClient.showDemo()@120: Gruppe [2801]: Republikaner (Die Partei der Republikaner)
  10. JPAClient.showDemo()@121: Benutzerzahl: 0

Das Problem ist offensichtlich: Während jeder Benutzer eine Referenz auf das ihm zugeordnete Gruppenobjekt hält, kennt keine der Gruppen die Benutzer, die ihr zugeordnet sind.

Die Lösung

Bidirektionale Beziehungen sollten eigentlich anders funktionieren. Das oben geschilderte Problem ist das, was auch vielen anderen wegen seiner Struktur Probleme bereitet. Die Beziehung funktioniert beidseitig und solange der gleiche EntityManager läuft, können Objekte vom JPA-Provider zwischengespeichert werden. Daher reicht ein einseitiges Zuweisen nicht aus, vielmehr muss in diesem Fall auch der Gruppe der Benutzer zugewiesen werden. Erst dann sind die zwischengespeicherten Objekte vollständig.

JAVA:
  1. EntityManager em = createEntityManager();
  2.  
  3.         final Gruppe g1 = createGruppe("Demokraten", "Die Partei der Demokraten");
  4.         final Gruppe g2 = createGruppe("Republikaner", "Die Partei der Republikaner");
  5.  
  6.         final Benutzer b1 = createBenutzer("Obama", "Barack", "bobama", "obama@senate.gov");
  7.         final Benutzer b2 = createBenutzer("McCain", "John", "jmccain", "mccain@senate.gov");
  8.         final Benutzer b3 = createBenutzer("Clinton", "Hillary", "hclinton", "clinton@senate.gov");
  9.  
  10.         b1.setGruppe(g1);
  11.         b2.setGruppe(g2);
  12.         b3.setGruppe(g1);
  13.        
  14.         g1.getBenutzer().add(b1);
  15.         g2.getBenutzer().add(b2);
  16.         g1.getBenutzer().add(b3)
  17.  
  18.         em.persist(b1);
  19.         em.persist(b2);
  20.         em.persist(b3);
  21.        
  22.         em.persist(g1);
  23.         em.persist(g2);

Folgende Ausgabe zeigt das Ergebnis der Ã?nderung:

CODE:
  1. JPAClient.showDemo()@107: Benutzer [2952]: Clinton, Hillary (hclinton, clinton@senate.gov)
  2. JPAClient.showDemo()@108:   +--> Gruppe [2850]: Demokraten (Die Partei der Demokraten)
  3. JPAClient.showDemo()@107: Benutzer [2951]: McCain, John (jmccain, mccain@senate.gov)
  4. JPAClient.showDemo()@108:   +--> Gruppe [2851]: Republikaner (Die Partei der Republikaner)
  5. JPAClient.showDemo()@107: Benutzer [2950]: Obama, Barack (bobama, obama@senate.gov)
  6. JPAClient.showDemo()@108:   +--> Gruppe [2850]: Demokraten (Die Partei der Demokraten)
  7. JPAClient.showDemo()@112: Lade Gruppen
  8. JPAClient.showDemo()@120: Gruppe [2850]: Demokraten (Die Partei der Demokraten)
  9. JPAClient.showDemo()@121: Benutzerzahl: 2
  10. JPAClient.showDemo()@126:   +--> Benutzer [2952]: Clinton, Hillary (hclinton, clinton@senate.gov)
  11. JPAClient.showDemo()@126:   +--> Benutzer [2950]: Obama, Barack (bobama, obama@senate.gov)
  12. JPAClient.showDemo()@120: Gruppe [2851]: Republikaner (Die Partei der Republikaner)
  13. JPAClient.showDemo()@121: Benutzerzahl: 1
  14. JPAClient.showDemo()@126:   +--> Benutzer [2951]: McCain, John (jmccain, mccain@senate.gov)

Diese Art der Zuweisung im Code eines Client-Programms ist natürlich etwas unschön, sinnvoller wäre es, diese Zuweisung gleich im entsprechenden Setter der Benutzerklasse zu machen.

JAVA:
  1. public void setGruppe(final Gruppe gruppe)
  2.     {
  3.         _gruppe = gruppe;
  4.         if (null != _gruppe.getBenutzer() && !_gruppe.getBenutzer().contains(this))
  5.         {
  6.             _gruppe.getBenutzer().add(this);
  7.         }
  8.     }

Das Problem erübrigt sich auch, wenn man einen anderen EntityManager verwendet als den, der die Objekte persistiert hat.

2 Kommentare