12 lutego 2010

Boimy się nieznanego, regularny wypoczynek z pływaniem i silnie typizowane zapytania w JPA2

Najbardziej uwielbiam te momenty, w których na usta ciśnie się "Eureka!". To jest ten moment, w którym wszystko układa się w jedną całość i brak w nim niewyjaśnionych miejsc. Można wtedy wygodnie rozłożyć się w fotelu i powiedzieć sobie "Udało się!" Wtedy wiem, że wysiłek nie poszedł na marne.

Uważam, że jest wiele rzeczy, które ostatecznie składają się na ten moment wzniosłości. Sam smak zwycięstwa to za mało, aby ucieszyć ślęczącego nad tematem programistę, który tak trwa w tym stanie ciągle, przez kilka ostatnich dni i zrekompensować mu poniesione straty. Ważne, aby w tym całym szaleństwie znaleźć jeszcze umiar w dążeniu do celu i znaleźć czas na relaks i wypoczynek. Właśnie wtedy, kiedy rozwiązujemy problem najbardziej potrzeba nam wypoczynku.

Spotkałem się z dwoma podejściami do rozwiązania problemu - siłować się z nim do momentu, aż albo on, albo ja, lub też, drugie podejście, gryźć problem kawałek po kawałku, rozkładając go na części pierwsze.

Zakładając, że oba kończą się tym samym - zwycięstwem - nie mam wątpliwości, w której ja chciałbym się znaleźć. Oczywiście w tej drugiej. Ostateczne zwycięstwo będzie dodatkowo udekorowane wieńcem końca zadania i wystarczających sił na kolejne.

Takie coś przytrafiło mi się dzisiaj z rana, kiedy po śniadaniu z Agatką, zasiadłem do pewnego tematu (na razie o nim sza) i wszystko wydało się takie oczywiste. A wystarczyły regularność i spanie > 7h. Rozwiązanie samo do mnie przyszło, zamiast mnie biegającego za nim.

Najbardziej w tym wszystkim zdumiewające było to, że problem był niezwykle błahy i wyłącznie moja nieznajomość tematu robiła z niego większego potwora niż było potrzebne. "Boimy się nieznanego", jak powiadają.

I tu jest właśnie sedno sprawy - ciągłe rozwijanie swojej wiedzy, ciągłe próbowanie się z nowym. Kiedy czegoś nieznamy, kolejne nieznane może nas łatwo sfrustrować, prowadząc do błędnego wniosku, że jedyne, co potrafimy, to odkrywać nieznane. To samo w sobie może być wartościowe, ale niewielu pomyśli o tym pozytywnie. Kiedy jednak owe poznawanie wpiszemy w kontrakt naszego działania i wejdzie nam w krew, przedzieranie się przez nieznane, będzie jedynie odkrywaniem kolejnego nieznanego, co z dobrym wypoczynkiem (!) może dawać satysfakcję jego odkrycia. Idąc dalej, to nieznane może być niezwykle dochodowe (przez "dochodowe" rozumiem nową wiedzę, nowe możliwości, itp.) W końcu może się nawet okazać, że nowe dla nas jest nowym dla większości wokoło, a to stawia nas w szeregu nowicjuszy...eee, raczej...nowatorów!

Zostawiając na boku ten cały bełkot psychologiczny, pamiętajmy o wypoczynku, regularnym wypoczynku. 7h minimum i 3 x 1/2h ciągłego pływania/tydzień, to obowiązek każdego programisty. Tak sobie to dzisiaj wymyśliłem. Siedzenie nas wykańcza, a problemy technologiczne nie pomagają.

Żeby nie było, że wpis taki umoralniający, bez pierwiastka javnego, to napiszę, że właśnie z ukończeniem rozdziału 9-tego "Criteria API" książka Pro JPA 2: Mastering the Java™ Persistence API stała się dla mnie lekturą obowiązkową każdego parającego się JPA czy ORMem w Javie. Jestem na 10 rozdziale (273. strona) i z trudem idzie mi jej czytanie. Nie dlatego, że taka beznadziejna, ale dlatego, że każda strona wypełniona jest wiedzą JPA po brzegi! Rozdział 9. "Criteria API", który właśnie skończyłem zajął mi prawie 4 dni i cały jest zakreślony notatkami. W zasadzie wszystko było nowe (nie dotykałem wcześniej tematu w Hibernate) i niezwykle zapadające w pamięć swoją złożonością (w sensie pozytywnym, bo w końcu wciąż może być jeszcze trudniej, bo wciąż możemy zejść na poziom SQLa i bawić się z przenośnością aplikacji przechodząc ze środowiska lokalnego, najczęściej z jakąś wbudowaną bazą danych typu HSQL, do testowego z DB2, Oracle, MySQL, czy innym SQLowym stworzeniem).

Co mnie najbardziej zainteresowało, to budowanie zapytań SQL z mechanizmem silnie typizowanych (jak ja nie lubię tego słowa) zapytań w JPA2 (ang. strongly typed query definition) z kanonicznym metamodelem. Brzmi wyniośle, a sprowadza się do zmiany nazw pól w mapowaniu ORM (w postaci napisów) na ich silnie typizowane odpowiedniki (w postaci pól w klasie reprezentującej kanoniczny metamodel encji). Zamiast pisać ...get("ksiazka").get("tytul") można ...get(Ksiazka_.tytul). Kiedy dodam, że dostawcy JPA2 generują takie klasy kanoniczne (zwykle zakończone podkreślnikiem po nazwie encji/klasy) i przy pisaniu zapytania pomaga nam każde IDE, bez specjalnego wsparcia dla JPA2, to zysk jest niebagatelny. Można wręcz całkowicie zapomnieć o trzewiach ORMa w postaci relacyjnej bazy danych - same obiekty i silna typizacja. I znowu zaczynam biegać za nowym :) Bawił się tym już ktoś?

4 komentarze:

  1. Cześć Jacek
    Mimo, że jestem fanem rozwiązań ORM (JPA/Hibernate w szczególności), to dopiero Twój post zmobilizował mnie, aby się na chwilę pochylić nad Criteria API z JPA 2 ;)

    Przeczytałem sobie fragment książki (via Google books), która czytasz (JPA 2) i faktycznie, z tego co widzę, od JPA 2 będzie dostępna funkcjonalność:
    get(Ksiazka_.tytul)

    ... czyli typesafe na poziomie języka (tutaj Java).

    Ale ja uparcie twierdzę, że ten mechanizm jest przekombinowany. Jak sam z resztą wspominasz, ten trik wymaga od dostawcy JPA 2 mechanizmu generowania klasy kanonicznej. Przykład takie klasy jest na stronie 268 (klasa Emplyee_).
    I według mnie, cała ta klasa kanoniczna (i smutna konieczność ich generowania przez framework JPA 2), jest tylko odpowiedzią, na brak uproszczonego mechanizmu refleksji na poziomie języka Java.

    Gdyby tylko Sun (khm, Oracle) zechaciał zaimplementować ten Java Feature Request:
    http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=5043025

    ... to mam wrażenie, że za pośrednictwem takiego mechanizm refleksji, można byłoby osiągnąć triki i mechanizm z Criteria API w JPA 2 bez konieczności używania jednak trochę pokracznych, nadmiarowych i napuszonych konstrukcji z dodatkowymi klasami kanonicznymi.

    Coż, jeśli kogos przekonałem, ze opisany w Feature Ewquest, uproszczony mechanizm refleksji jest interesujący, to zachęcam zatem na oddanie swojego głosu na ten Feature Request :)
    Ja taki głos oczywiście już dawno oddałem :)

    OdpowiedzUsuń
  2. Zgadzam sie z przedmowca, literaly dla pol i metod bylyby swietne w tym i wielu innych przypadkach. A samo typesafe criteria api nie iwem po co jest, jedyne co mi przychodzi do glowy to dynamiczne tworzenie zapytan na stronce, gdzie user moze sobie dodawac kryteria wyszukiwania - zamiast babrania sie stringami mamy takie cos. Jakos tego nie lubie.

    OdpowiedzUsuń
  3. Cześć Jacku

    Popieram jak najbardziej Twoje refleksje nad kondycją psycho-fizyczną :) Od jakiegoś czasu przestawiłem się na poranne wstawanie i minimum 7 godzin snu. To czego mi jeszcze brakowało, a o czym wspomniałeś to pływanie.
    Oczywiście początkowo wydawało mi się, że teraz muszę się pożegnać z wieloma aktywnościami, które sprawiały mi dużo przyjemności. Jednak z perspektywy kilku ostatnich tygodni widzę, że to wszystko tkwi raczej w podejmowaniu właściwych wyborów. A i tak zawsze będzie wiele spraw, których nie jesteśmy w stanie zrobić tu i teraz.

    Dobry wypoczynek to świerza energia, świerze spojrzenie na to wszystko co nas spotyka każdego dnia :)

    OdpowiedzUsuń
  4. @Wujek
    Kiedyś przechodziłem okres zauroczenia Hibernate criteria API (z racji właśnie ich typesafe), ale po jakimś czasie doszedłem do tego samego wniosku co i Ty (i inni również): przy bardziej złozonych zapytanich, które w HQL (które typesafe nie jest niestety) da się zapisać w miarę zwięźle, w Criteria zwięźle to już nie wygląda – jest niestety nieczytelne.
    Też się zgadzam z Tobą, Wujek, że Criteria pokazują swój pazur w dynamicznie (runtime) tworzonych zapytaniach – wspomniany przykład z kryteriami wyszukiwania na stronce jest trafnym przykładem.
    Jak pisałem, lubie ORMy, Hibernate / JPA w szczególności, ale nie widzę (niestety!) możliwości, aby te ORMy zrobić bardziej typesafe bez … zmiany języka. Mam wrażenie, że bez wspomnianych literałów (prostszy mechanizm refleksji) i bez np. przeciążania operatorów, raczeni nie będzie możliwe uproszczenia Cirteria API, takiego jakiego znamy z Hibernate / JPA 2.
    Lubi ę przyglądać się konstrukcjom z języka Scala. Nie napisałem w nim ani linijki kodu, ale język ten mi się podoba ;) Mam wrażenie, że dopiero tak elastyczny i zwięzły język jak skala, mógłby dokonać kolejnego skoku w kierunku uproszczenia i przejrzystości typesafe zapytań w ORM’ch.

    OdpowiedzUsuń