czwartek, 18 października 2007

Crazy JPA Requirements

Ostatnio w pracy przenosimy DAO z bezpośredniego SQL + JDBC do JPA (hibernate).
Niestety zapytania są budowane dynamicznie (niektóre kolumny i różne kryteria - between, like, or) i chyba nawet w czystym SQLu byłoby to łatwiej zrobić.
Z drugiej strony JPA jest bardziej elastycznie i błyskawicznie mamy zapisywanie encji. Czas pokaże czy był to dobry wybór.

Gładko te przenosiny oczywiście nie poszły. Dzisiaj np. cały dzień walczyłem z wyjątkiem NPE rzucanym z metody o śmiesznej nazwie:

findIntendedAliasedFromElementBasedOnCrazyJPARequirements

java.lang.NullPointerException
at org.hibernate.hql.ast.tree.FromClause.findIntendedAliasedFromElementBasedOnCrazyJPARequirements(FromClause.java:120)
at org.hibernate.hql.ast.tree.FromClause.getFromElement(FromClause.java:107)

Cóż, widać, że programiści Hibernate mają poczucie humoru i pewnie w ten zabawny sposób wyrazili swoje niezadowolenie z wymagań JPA.
Sam błąd okazał się znany (wariant twierdzenia Defecińskiego) i nawet znaleziony dawno, bo w wersji 3.2.0 GA. Ja obecnie używam hibernate 3.2.5 GA ale nadal kod jest niepoprawiony.
Co i jak poprawić jest napisane w tym issue na JIRA hibernate.

czwartek, 27 września 2007

Twierdzenie Defecińskiego (generic toString())

Przy pisaniu jUnit-ów nadpisałem sobie metodę assertEquals(MyObject expected, MyObject actual) dla moich obiektów (właściwie to używana jest assertEquals(Object, Object) a nadpisana jest metoda equals). Jeśli ta assercja jest nieprawdziwa to dostaje się coś w rodzaju expected: MyObject@23123 but got MyObject@323232Oczywiście dlatego, że używana jest metoda toString() z Object.

Napisanie własnej metody toString() jest dobrym rozwiązaniem, ale jeśli mamy kilka różnych obiektów a obiekty mają dużo parametrów to pisanie swoich toString może być męczące. Jeśli dodamy jeszcze do tego to, że podczas developmentu nasz obiekt ciągle się zmienia tj. dochodzą nowe pola, stare znikają to utrzymywanie toString() zsynchronizowanego ze stanem naszej klasy jest trudne.

Pogooglałem i znalazłem szybko ToStringHelper. Oparte o refleksję wypisuje klarownie nazwę i wartości wszystkich pól w obiekcie oraz klas nadrzędnych. Działało to fajnie dopóki jedna klasa nie zmieniła się i zyskała jedno pole wskazujące na swego rodzica (w sensie referencji). Powstała pętla obiektów i toString powodował StackOverflowError :-(.

Posiedziałem nad tym troszkę i napisałem wersję, która byłaby na to odporna. Spodobało mi się, że rozwiązałem problem i chciałem "sprzedać" mój pomysł koledze. Jak wysyłałem mu maila to jeszcze raz zagooglałem o "generic to string" żeby podać link do ToStringHelper ...

... a znalazłem ReflectionToStringBuilder z commons-lang, który robił dokładnie to samo co "mój" toString (nawet ten sam output!) i także nie powodował przeciążenia stosu. Zawsze twierdziłem, że cokolwiek nie wymyślę to istnieje ktoś w sieci kto już to napisał. Myślę, że nazwę to kiedyś twierdzeniem Defecińskiego :D (jak tylko przeprowadzę dowód).

środa, 26 września 2007

SCJP

Udało się zdać SCJP na 91%. Niby dużo, ale znam takich co mieli więcej :-).

Teraz chyba mogę zacząć pisać blog programisty JAVA. Zawsze wydawało mi się, że trochę za mało wiem, żeby tytułować się programistą JAVY czy jakiegokolwiek innego języka. Tak na prawdę im więcej wiesz tym widzisz jak wiele jeszcze nie umiesz.

Jak kończyłem studia (Politechnika Łódzka/FTIMS) to wydawało mi się, że znam język dość dobrze. Potem dwa lata po studiach kiedy zacząłem przygotowania z SCJP okazało się, że bardzo się mylę. No ale przygotowałem się, zdałem (najsłabiej API contents ale kto tam pamięta metody z DateFormat ?) i ... nadal przede mną wiele tajemnic.

Co do przygotowywania się to może ktoś będzie zainteresowany z czego korzystałem:
książki i testów jqplus. Książkę warto przeczytać, ale najwięcej nauczyłem się rozwiązując testy z JQ+.

Testy robili Hindusi i mają one trochę błędów, ale raczej można to wychwycić i/lub sprawdzić z kompilatorem. JQ+ jest też 2x tańszy od innych pomocy naukowych (Whizlab, uCertify, Troytec) dlatego bym go polecił. Na egzaminie nie było praktycznie pytań identycznych (a z Troytec podobno 90%) ale przecież nie chodzi o naukę na pamięć tylko o zrozumienie tematu.

Powodzenia!