Ha használunk Sonatype Nexus-t abból a célból, hogy a Maven alapú csomagjainkat biztos helyen tartsuk, akkor nem árt időnként ránézni a repository méretére, mert alapból a -SNAPSHOT csomagok nem törlődnek, így intenzív használat esetén a sonatype-work mérete az egekbe szökhet, mivel csak gyűlnek a feltöltött csomagok, amelyek közül általában csak az utolsót használjuk.
A probléma elkerülése érdekében célszerű egy naponta futó feladatot felvenni az Administration alatti Scheduled Tasks menüpont alatt az Add gomb használatával:
Mentés után jelöljük ki a feladatot és a Run gomb megnyomásával futtassuk le, ezek után a beállított időközönként le fut futni, a hibás lefutásról emailben kapunk jelentést.
Egy május eleji hosszú hétvége gondolatait összegezve írtam meg május harmadikán a hírhedt Le roi est mort, vive le roi! című hozzászólást, amely lényege annyi volt, hogy a javaforum.hu portál tartalmát Confluence alá migrálom. A bejegyzés kisebb vitát generált a Java levelezőlistán, sokunk véleménye ütközött, néhányan egyszerűbb PHP alapú portált szerettek volna, mások a Confluence-t találták túl nagy dolognak, nagy többség által támogatott konszenzus nem alakult ki, de abban szinte mindenki egyetértett, hogy változtatni szükséges. Május hatodikán sikeresen importáltam a felhasználókat a Crowd alá (bár néhány jelszó elveszett), majd május tizennegyedikén a migráció pilot során néhány jelentéktelenebb témán kipróbáltam a tartalom átmásolását, ezt követte egy hétnyi tartalom migráció, majd május 23-án éjjel megtörtént az átállás, illetve 26-án csendben megünnepeltük a hatodik évfordulót...
Mint arról már írtam néhány napja: a javaforum.hu alatti szerver kissé koros, lassú, és nehezen bővíthető; a Confluence viszont kissé erőforrás igényesebbnek bizonyult, mint a régi portál, így a szűkös erőforrásokon egymással harcoló szolgáltatások miatt a rendelkezésre állás jelentősen leromlott, az áprilisi közel 100 százalékos (tisztán JavaForum2.0) rendelkezésre állás június harmadik hetéig 98,9 százalékra esett vissza – a netdiag.hu módszertana szerint a 12 másodpercnél hosszabb válaszidő ugyanis hiba. A grafikonokon szépen látszik, amit érezni is lehetett gyakran: a tartalmakhoz való hozzáférés az utóbbi négy hétben nehézkes volt, több kiesés és lassulás is előfordult, számszerűen mintegy 8 órán át nagyon lassú volt a Confluence oldalak létrehozása, s további 8 órán át túllépte a 12 másodpercet is a tartalmak előállítása, és sokszor órákon-napokon át 2-3 másodpercig is eltartott a főoldal legenerálása.
A megoldás az lett, hogy a fizikai gépről virtuális gépre költöztetem át a szolgáltatásokat, a Confluence már négy napja az új szerveren fut, az első napon a CentOS részeképp feltelepülő OpenJDK probléma okozott némi izgalmat, de amióta a Oracle Java 6 van a portál alatt, azóta nem történt fennakadás, remélem ez így is marad. Nincs okom panaszra a virtualizált erőforrásokat tekintve, a nagyobb migrálások alatt is csak belassult a kiszolgálás (elfogyott a CPU erőforrás), de hamar visszaért a 800-900ms közötti válaszidőre a http://wiki.javaforum.hu oldal tartalmának előállítása. A technikai részletekről elég ennyi...
Feltettem magamnak a komplex kérdést, hogy jó lesz-e a Confluence, mint tartalomkezelő rendszer, képes-e átvenni a régi portál helyét? A válasz jelenleg az, hogy igen. Sokkal könnyebb tartalmakat létrehoznom, módosítanom, szerkesztenem, mint a JavaForum2.0 esetén, ahol a szerkesztőségi rendszer néha egy INSERT INTO kezdetű sor volt az adatbázis konzolon. Sokat segítenek a letölthető és telepíthető plugin programok, amelyek egy kattintásra kiterjesztik a lehetőségeket, illetve olyan tulajdonságokkal ruházzák fel az alap Confluence oldalakat, amelyek nagyon kézre állnak.
Ha magamat nem számítom, akkor azt kell mondjam, hogy szinte csak a hírekre jöttek a megjegyzések, az első két hét szinte csendben eltelt, aztán több fórumbejegyzés is létrejött, a portál látogatottság lassan, de növekedett, sajnos a közösségi szellem még nem tesz körsétákat, de talán idővel ez is megoldódik...
Ha jól körülnézek, akkor három területen lenne szükségem segítségre:
- olyan területen híreket írni, amelyhez nem értek kellően (Eclipse, Spring, stb)
- a portál jelenleg az Intranet témát használja, ezt kicsit gatyába kellene rázni design ügyileg
- kezdőknek szóló leírásokat létrehozni különféle témákban
A meghirdetett Cikkért könyv! egyelőre nem váltotta be a reményeimet, de nem adom fel...
Ti mit gondoltok? Szerintetek jó lesz a Confluence?
Elnézést kell kérjek, hogy az utóbbi egy hétben nem jelent meg új hír, de a Confluence motorra való migrálás nem várt teljesítményproblémákat okozott a jelenlegi szerveren, így egy újabb stabil alap után kellett néznem: egy VPS lett a befutó.
A migrációs sztorit a rendszergazdai dolgok iránt érdeklődők a Home oldalon olvashatják, a mai aktuális szívást pedig a OpenJDK probléma oldalon...
A Java 5 hozott néhány újdonságot a párhuzamos programozás terén, a Java 7 további könnyítéseket tartalmaz, amelyek közül az egyiket Fork/Join néven találjuk meg a dokumentációt böngészve, s a megoldás használatához csak három osztályt kell megismernünk:
- RecursiveAction – visszatérési érték nélküli feladat
- RecursiveTask – visszatérési értéket adó feladat
- ForkJoinPool – a szálakat kezelő osztály (thread pool)
Az elnevezésekből láthatjuk, hogy alapvetően hosszabb ideig tartó rekurzív feladatokra találták ki ezt a technológiát, mint a fájlrendszer felderítése vagy egy weboldal letöltése, de remekül használható matematikai és/vagy fizikai szimulációkhoz is. A RecursiveTask dokumentációs oldalán egy tipikus rekurzív feladat: a Fibonacci számsor kiszámolása a példa, nézzük meg közelebbről.
public class Fibonacci extends RecursiveTask<BigInteger> { final Integer number; public Fibonacci(final Integer number) { this.number = number; } @Override public BigInteger compute() { if (number <= 1) { return new BigInteger("" + number); } final Fibonacci f1 = new Fibonacci(number - 1); f1.fork(); final Fibonacci f2 = new Fibonacci(number - 2); f2.fork(); return f2.join().add(f1.join()); } }
Két fontos dolgot kell észrevennünk:
- Az osztály a RecursiveTask osztályból származik és implementálja a compute metódust az átadott BigInteger típus szerint (mivelhogy nagy számokkal dolgozunk).
- Létrehozunk két példányt, amelyeket a fork használatával elindításra jelölünk, majd a join hívással várjuk meg az eredményeket.
A használatához kell egy új osztály, amely létrehozza a ForkJoinPool példányt, majd elindítja a folyamatot, ezt alább látjuk:
public class App { public BigInteger computeFibonacci(Integer number) { final Fibonacci fibonacci = new Fibonacci(number); final ForkJoinPool fjPool = new ForkJoinPool(5); return fjPool.invoke(fibonacci); } public static void main(String[] args) { final Integer number = Integer.parseInt(args[0]); final App app = new App(); System.out.println(app.computeFibonacci(number)); } }
Ez esetben a lényeg a computeFibonacci metódusban van, ahol létrehozunk egy új Fibonacci osztályt, egy új ForkJoinPool osztályt maximum öt szállal, majd egyszerűen az invoke használatával elindítjuk a többszálú folyamatot. A szálak számáról és a ForkJoinPool gondoskodik, a szálak indításáról és lezárásáról pedig a RecursiveTask ősosztályban megvalósított fork és join metódusok: a fejlesztőnek egyszerűen csak a feladatra kell koncentrálnia, minden mást megold a Java 7.
Megfelelően nagy számmal indítva – az 40 már bőven sok – láthatjuk, hogy egy négymagos (nyolcutas) i7 processzort szépen kiterhel öt szálon az adott java processz (495%):
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 7268 auth.gab 20 0 1191m 391m 7024 S 495 5.0 8:26.22 java
Ha megnöveljük a használt szálak számát, akkor egészen a processzor végső határig tudjuk növelni a párhuzamosságot (736%):
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 7442 auth.gab 20 0 1192m 369m 7008 S 736 4.7 1:52.95 java
A kapott eredményt leellenőrizhetjük a maths.surrey.ac.uk adott oldalán; 40 esetén ez 102334155 kell legyen.
Ahogy a grafikonon látni, fél évente közel 200 ezerrel növekszik a naponta aktivált Android eszközök száma, amely nyilván nem növekedhet a végtelenségig, a jelenlegi egyenes el kell laposodjon idővel.

Operációs rendszer | Millió eladott példány |
---|---|
Android | 89.9 |
iOS | 35.1 |
Symbian | 10.4 |
BlackBerry OS | 9.7 |
Bada | 3.5 |
WP7/WM | 3.3 |
Egyéb | 0.4 |
Érdekesség, hogy 2012 első negyedévében (forrás: IDC felmérés) az eladott kb. 150 millió okos-telefonból 90 millió Android operációs rendszerrel kelt el, amely az iOS rendszerrel együtt felhasználókat "rabol" a leszálló ágban lévő Symbian és BlackBerry elől, a Windows Phone 7 pedig továbbra is a nullától eltérő piacszerzéssel van elfoglalva...
Egy új tartalomfejlesztési modellt próbálunk bevezetni, amely remélhetőleg megmozgatja a közösség tagjait, az új modell fedőneve: cikkért könyv!
Ha úgy érzed, hogy van benned némi tudás, amelynek közzétételére már csak egy kis késztetés hiányzott, akkor itt a lehetőség:
- Írj cikket tetszőleges témában (cikk, wiki, ismertető, bemutató, hír):
- küldd el az info@javaforum.hu címre, átnézzük, hogy minőségi tartalom kerüljön ki
- kérj javaforum-blackbelt jogot, hogy önállóan fel tudd tölteni az írásod a cikkek közé
- Érj el minél több és jobb értékelést a megjelenést követő egy hónap alatt (Confluence rate macro, Google +1, Facebook Like):
- Minden megosztás öt pont
- Minden értékelésnél egy csillag egy pont
- Szavazz a kedvenc könyvedre július elsejéig
- Eredményt mindig a JUM következő eseményén hirdetünk, a pontokat a JUM napján számoljuk ki!
Üdvözlettel,
Gépház
A Java7 egyik csendes újítása a java.util.Objects osztály, amely közel tucatnyi statikus metódust ad az objektumok kezeléséhez, amely metódusok egy része nem esik zavarba, ha null értéket kap. Az Objects tipikus esete utility osztályoknak, final módosítóval van ellátva, illetve van egy privát konstruktora is:
private Objects() { throw new AssertionError("No java.util.Objects instances for you!"); }
Suhanjunk végig az eddig megvalósított metóduslistán...
equals
Az első metódus egy egyszerű egyezőség vizsgálat, amely levizsgálja a két összehasonlítandó paraméter közül az elsőt, hogy annak értéke nem null, majd ezek után végzi el az összevetést, így ez a metódus null safe: használata során nem kell NullPointerException kivételre számítanunk. A forrása egyszerű:
public static boolean equals(Object a, Object b) { return (a == b) || (a != null && a.equals(b)); }
Használata:
String a = null; String b = null; System.out.println(Objects.equals(a, b)); b = "nem üres"; System.out.println(Objects.equals(a, b)); a = "nem üres"; System.out.println(Objects.equals(a, b));
Az eredmény:
true false true
deepEquals
A deepEquals metódus hasonlít a fentire, de sima equals helyett az Arrays.deepEquals metódust hívja meg null ellenőrzéssel, így egy sorban tudunk két tömböt összevetni:
public static boolean deepEquals(Object a, Object b) { if (a == b) return true; else if (a == null || b == null) return false; else return Arrays.deepEquals0(a, b); }
Használata:
String[] a = null; String[] b = null; System.out.println(Objects.deepEquals(a, b)); b = new String[]{"semmi", "újabb semmi"}; System.out.println(Objects.deepEquals(a, b)); a = new String[]{"semmi", "újabb semmi"}; System.out.println(Objects.deepEquals(a, b));
Az eredmény:
true false true
hashCode
A hashCode lehetőséget ad null safe hívásra, az átadott objektumnak csak akkor hívódik meg a hashCode metódusa, ha a paraméter nem null:
public static int hashCode(Object o) { return o != null ? o.hashCode() : 0; }
Használata:
String a = null; System.out.println(Objects.hashCode(a)); a = "semmi"; System.out.println(Objects.hashCode(a));
Az eredmény:
0 109322039
hash
Hasonlít az előzőre, azzal a különbséggel, hogy a metódus paraméterlistája dinamikusan bővíthető, s az eredményül kapott objektum-tömb átadásra kerül a Arrays.hashCode metódusnak, így lehetőségünk van null biztos hash képzésre több argumentumból:
public static int hash(Object... values) { return Arrays.hashCode(values); }
Használata:
String a = null; String b = null; System.out.println(Objects.hash(a, b)); b = "semmi"; System.out.println(Objects.hash(a, b)); a = "semmi"; System.out.println(Objects.hash(a, b));
Az eredmény:
961 109323000 -796661087
toString
Ez a metódus kissé kilóg a többi közül, mert null biztos konverzióra eddig is lehetőség volt az alább is látható String.valueOf(o) használatával:
public static String toString(Object o) { return String.valueOf(o); }
Használata:
String a = null; System.out.println(Objects.toString(a)); a = "semmi"; System.out.println(Objects.toString(a));
Az eredmény:
null semmi
toString + alapértelmezett érték
Az előzőnél sokkal hasznosabb metódus a most következő, amelynél megadhatunk egy alapértelmezett értéket, ha az átadott objektum értéke null:
public static String toString(Object o, String nullDefault) { return (o != null) ? o.toString() : nullDefault; }
Használata:
String a = null; System.out.println(Objects.toString(a, "hopsza, ez null")); a = "semmi"; System.out.println(Objects.toString(a));
Az eredmény:
hopsza, ez null semmi
compare
A compare metódus két objektum összehasonlítására jó, s ez a többi metódushoz képest két okból is rendhagyó:
- nem null safe
- kell neki egy Comparator implementáció, amely szükség esetén lehet null safe
public static <T> int compare(T a, T b, Comparator<? super T> c) { return (a == b) ? 0 : c.compare(a, b); }
Használata (hibát okoz):
Comparator<String> comparator = new Comparator<String>() { public int compare(String o1, String o2) { return o1.compareTo(o2); } }; String a = null; String b = null; System.out.println(Objects.compare(a, b, comparator)); b = "semmi"; System.out.println(Objects.compare(a, b, comparator)); a = "semmi"; System.out.println(Objects.compare(a, b, comparator));
Az eredmény:
0 Exception in thread "main" java.lang.NullPointerException at hu.javaforum.showobjects.App$1.compare(App.java:19) at hu.javaforum.showobjects.App$1.compare(App.java:15) at java.util.Objects.compare(Objects.java:181) at hu.javaforum.showobjects.App.main(App.java:27)
requireNonNull
Ez egy nagyon hasznos metódus, jegyezzük meg, mert nem csinál ugyan sokat, de azt gyakran használjuk, ha paramétereket ellenőrzünk! Megvizsgálja, hogy az átadott első paraméter null értékű-e, ha igen, akkor dob egy NullPointerException kivételt, ha nem, akkor visszaadja az objektumot:
public static <T> T requireNonNull(T obj) { if (obj == null) throw new NullPointerException(); return obj; }
Használata:
String a = Objects.requireNonNull("semmi"); System.out.println(a); String b = Objects.requireNonNull(null); System.out.println(b);
Az eredmény:
semmi Exception in thread "main" java.lang.NullPointerException at java.util.Objects.requireNonNull(Objects.java:201) at hu.javaforum.showobjects.App.main(App.java:17)
requireNonNull + szöveg
Hasonló a fentihez, ám ez esetben megadhatunk egy szöveget, amely adott esetben átadódik a NullPointerException kivételnek:
public static <T> T requireNonNull(T obj, String message) { if (obj == null) throw new NullPointerException(message); return obj; }
Használata:
String a = Objects.requireNonNull("semmi", "A paraméter értéke null"); System.out.println(a); String b = Objects.requireNonNull(null, "A paraméter értéke null"); System.out.println(b);
Az eredmény:
semmi Exception in thread "main" java.lang.NullPointerException: A paraméter értéke null at java.util.Objects.requireNonNull(Objects.java:226) at hu.javaforum.showobjects.App.main(App.java:17)
Konklúzió
Nagyon hasznos osztály, használja mindenki – aki teheti, ugyanis nagyon sok saját osztály van a projektjeinkben, amelyek hasonló vagy pontosan ilyen módon működnek, mivel egy-egy fenti metódus használatával a forráskódunk egyszerűbb és átláthatóbb lesz, másrészt kevesebb saját forráskódot kell majd karbantartanunk.
(inspiráció: www.javabeat.net/2012/06/java-util-objects-a-static-utility-for-objects-introduced-in-java-7/)
Szerda délelőtt lezajlott a JBoss User Forum, amely rendezvény során a Red Hat megpróbálta bemutatni, hogy mit is szeretne kezdeni a JBoss technológiákkal, így meghívót küldtek az JBoss megoldások iránt érdeklődő hazai szakembereknek és bemutatták. A minikonferencia szokás szerint kiadós kávézással és pogácsázással kezdődött, de sajnos túl nagy tömeg nem gyűlt össze: az előadókkal és szervezőkkel együtt talán két tucatnyi ember verődött össze az első előadás kezdetéig, amelyet Marcin Labanowicz – a Red Hat kelet európai ügyfelekkel foglalkozó embere – tartott, s alapvetően a Red Hat bemutatásáról szólt.
Ezt követte Dominik Watruba (Senior Solution Architect) előadása a JBoss AS (Community) és a JBoss EAP (Enterprise Application Platform) közötti különbségekről. Megerősítésre került az a közismert tény, hogy az Enterprise verzió a Community verzión alapul, ám a közösségi kiadásba nem kerülnek javítások és frissítések (leszámítva a rendszertelen időnként kiadott alverziókat), a támogatott kiadás ellenben rendszeresen frissül, illetve a felderített hibák is kijavításra kerülnek. Ezen túl az Enterprise kiadás 7 éves támogatási ciklusának első négy évében a nagyobb és fontosabb újdonságok belekerülnek backport formájában (a közben kiadott Community verzióból). A Red Hat – úgy tűnik – ráállt arra a kiadási modellre, hogy a páratlan verziójú Community verzióból lesz Enterprise release, így lett JBoss AS 5.1 a JBoss EAP 5 alapja, illetve így lett a hamarosan megérkező EAP 6 alapja a JBoss AS 7.1. Az előadás második fele a Red Hat middleware megoldásait mutatta be, amely során a SOA-P összeköti az új Java alkalmazásokat a legacy rendszerekkel, illetve a nem Java alkalmazásokkal; e mellett a Data Services Platform tartja a kapcsoaltot a SOA-P és az adatbázisok (adatforrások) között; ezek felett van a JBoss Business Rules Management System; végül az egészet az Enterprise Portal Platform koronázza meg. Dominik fontosnak tartotta kiemelni, hogy az "eating your own dog food" szellemében a Red Hat a saját termékein működik, saját operációs rendszerén fut a saját portál megoldása a saját alkalmazás szerverükben.
Dominik után Szentiványi Gábor következett, aki röviden bemutatta az ULX céget, majd rátért a cloud és a SOA bemutatására: mindkettő régóta divatos szó az informatika területén, de mostanság kezdik megérteni a vállalatok, hogy mire is jó a cloud, illetve hogyan működik egy jó SOA. Gábor előadását egy kávészünet követte, amely során lehetett pogácsázni, illetve kapcsolat hálót építeni egy kis sütizés közben.
Az ebéd előtt másfél órával folytatódott a konferencia, ismét Dominik adott elő: a JBoss EAP 6 újdonságairól:
- Újratervezték az alapoktól, ez meg is látszik a JBoss AS 6.x és a 7.x közötti jelentős különbségekben
- Multi-node alapú működés (a többi alkalmazás szerverhez hasonlóan lett egy domain-controller)
- Újragondolt menedzsment API jött létre (CLI, Java, REST, XML, Web konzol), a menedzsment felületen kiadott módosítások belekerülnek az XML konfigurációba
- A konfiguráció sokkal egyszerűbb lett, egyetlen XML (domain.xml) tárolja az adott példány összes beállítását, ezt szét tudja szinkronizálni a cluster tagjaira
- A Java EE 6 megfelelőség okán megjelentek a profilok
- Új és hatékony technológiák jelentek meg: HornetQ, több magot végletekig kihasználja, Infinispan cache réteg
- Nagyon gyors – 6 másodperc alatt indul, 9MBájt memóriát használ (!), a szolgáltatások igény esetén indulnak csak el
Ezek után – a pogácsák, a sütik és az újdonságok emésztése közben – a Wit-Sys nevű cég mutatta be, hogy mostanában JBoss technológiákat használva fejlesztenek, és ez mennyiben könnyítette meg a fejlesztők életét, illetve rövidítette le a fejlesztési ciklust. Az utolsó előadást Vámosi Tamás tartotta, bemutatva a Red Hat támogatási modelljét, hosszasan részletezve, hogy a konkurens Oracle és IBM megoldásainál mennyivel olcsóbb a Red Hat megoldása egy három éves fejlődési ciklust tekintve. Az ebéd előtt kisorsolásra került öt darab JBoss póló, az ebéd közben pedig hasznos pletykákat osztottak meg egymással az IT piac résztvevői.
Összességében azt mondanám, hogy megérte elmenni erre a kis konferenciára, főképp Dominik Watruba okán, aki remek előadó, kiválóan tudta vegyíteni a technikai újdonságokat a marketing mondásokkal, így lazán és mosolyogva terelte a figyelmet az Enterprise kiadások felé. A többi előadás számomra nem mondott újat, illetve a Red Hat támogatás költségvetési oldala nem az én asztalom, de nyilván voltak résztvevők, akiket ez érdekelt jobban...
A héten megjelent a Spring for Android csomag, amely lehetővé teszi, hogy Android telefonról elérjünk a Spring szerveren futó szolgáltatásainkat REST interfészen keresztül. A HTTP csatornán használhatunk XML vagy JSON szerializációt, illetve a Spring keretrendszer authentikációs szolgáltatását.
Rövid összefoglaló a fejlesztés menetéről:
Ahogy azt a Welcome című hírben megfogalmazta: a JDF megmutatja a fejlesztőknek, hogy miképp lehet JBoss és JavaEE 6 technológiákkal fejleszteni a JBoss EAP és a JBoss AS platformra.
Egyszerű példák
Kicsi és egyszerű dolgokat találunk a quickstarts oldalon, ahol minden egyes példácska erősen egy témára koncentrálódik, bemutatva egy API-t vagy egy használati esetét. Jelenleg 53 ilyen kis téma érhető el a JAX-RS-től kezdve a GWT-n át a tranzakciókezelésig.
Összetett példák
Az egyszerű példák hasznos dolgok, de minden fejlesztőnél eljön az ideje a nagyobb alkalmazás megírásának, amely mindenképpen több, mint az egyszerű példák. A TicketMonster egy összetettebb alkalmazásnak is beillik, amelyen bemutathatóak egy web alkalmazás fontosabb részei, különös tekintettel a felhasználói felületre, amely lehet HTML5+REST, GWT vagy JSF.
Migráció
Ha megismertük a Java EE 6 világát és a köré épülő technológiákat, akkor hasznosak lehetnek a segédletek, amelyek megmutatják, miképpen tudunk régebbi vagy eltérő technológiákról (Seam, Spring, JavaEE 5, stb) migrálni ezen újonnan megismert eszközökre.
Egyebek
Találunk a projekt kapcsán BOM fájlokat, illetve érdemes felkeresni a fórumot (amely még kissé üres, de remélhetőleg megtelik élettel).
A JPA első kiadása nem tartalmazta a Hibernate felhasználói között népszerű Criteria lekérdezést, amely – kisebb változtatásokkal – része lett a JPA 2.0 specifikációnak. A CriteriaQuery nagyon jól használható olyan lekérdezésekhez, amelyeknél paraméterből jön a szűrni kívánt mező, vagy a rendezendő oszlop. Az egyetlen probléma a végrehajtott JPQL/SQL lekérdezése, amely két okból is jól jöhet:
- kinyerni egy jó és tömör JPQL lekérdezést, amely fedi a Criteria tömörségét
- hiba keresésénél kiírni a naplóba a végrehajtott JQPL vagy SQL utasítást
Van egy jó és egy rossz hírem: a jó hír az, hogy van erre lehetőség. a rossz hír pedig az, hogy JPA provider függő.
Criteria lekérdezés
Készítsünk egy átlagos Criteria lekérdezést:
CriteriaBuilder cb = em.getCriteriaBuilder(); CriteriaQuery<Book> q = cb.createQuery(Book.class); Root<Book> b = q.from(Book.class); q.select(b).orderBy(cb.desc(b.get("id"))); TypedQuery<Book> findAllBooks = em.createQuery(q);
JPQL/SQL utasítás lekérdezése
A fenti forráskód eredményeképp előáll egy TypedQuery, amelyből kiindulva le tudjuk kérdezni az JPA provider által előállított JPQL vagy SQL utasítást.
EclipseLink
EclipseLink esetén lehetőségünk van lekérdezni az SQL utasítást, ha már az adatbázisig eljuttattuk a kérést (különben null eredményt kapunk):
findAllBooks.unwrap(org.eclipse.persistence.jpa.JpaQuery.class).getDatabaseQuery().getSQLString();
Hibernate
Hibernate esetén egy nem kell lekérdeznünk a DatabaseQuery példányt, a getQueryString azonnal visszaadja a kívánt SQL utasítást:
findAllBooks.unwrap(org.hibernate.Query.class).getQueryString()
OpenJPA
OpenJPA esetén is elég a getQueryString, viszont ez nem SQL, hanem JPQL utasítást ad vissza:
findAllBooks.unwrap(org.apache.openjpa.persistence.QueryImpl.class).getQueryString()
Mit hoz a jövő?
Mielőtt belemerülnénk a fenti megoldások használatába, nézzünk körül a JPA 2.1 háza táján, ugyanis a 2.1 már specifikálja a JPQL és az SQL utasítás lekérdezhetőségét a getJPQLString és a getSQLString használatával, amelyet az EclipseLink már többé-kevésbé támogat is.
A University of California, Irvine Extension nyílt és ingyenes webináriumot hirdetett Amazon Web Services for Java Developers címmel, minden bizonnyal az azonos című és tematikájú képzésük bemutatása okán. Az online követhető esemény július hetedikén lesz a helyi idő (PST) szerint 11:30 – 12:30 között, amely kis hazánkban 21:30 – 22:30 közötti időszakot jelenti – így egy kellemes késő esti továbbképződésen vehetünk részt. A webináriumra bárki regisztrálhat, a kurzust Craig S. Dickson vezeti, aki 15 évnyi tapasztalattal rendelkezik, a fő érdeklődési területe a Cloud architektúra és az Enterprise Java.
Update
Lezajlott az előadás, amely megtekinthető:
A múlt héten az esküdtszék döntése szerint a Google nem sértette meg az Oracle szabadalmait, az Oracle ezért beadott egy indítványt, amellyel a döntést a bíró kezébe helyezi, de a stratégia nem jött be, Alsup bíró elutasította az Oracle kérését. Ezen túl a Groklaw portálon olvasható tegnapi tudósítás szerint az Oracle újabb vereséget szenvedett a bíróságon: Alsup úgy döntött, hogy a Java API nem védett a szerzői jog szerint, mivel az API duplikálható az interoperabilitás okán:
The overall name tree, of course, has creative elements but it is also a precise command structure — a utilitarian and functional set of symbols, each to carry out a pre-assigned function. This command structure is a system or method of operation under Section 102(b) of the Copyright Act and, therefore, cannot be copyrighted. Duplication of the command structure is necessary for interoperability....
Ezzel a Java API-t érintő kérdések a Java közösség számára megnyugtatóan végződtek – feltéve, hogy az Oracle nem fellebbez a témában.
A Google már csak a tényleges – Apache Harmony projektből örökölt – Java implementációkkal kapcsolatos szerzői jogsértésért felel, amelyért az Oracle nem tud milliárdokat leakasztani, ha pedig a Google újraírja ezeket a részeket, akkor az Oracle csak aprópénzt tud kicsikarni a jogsértésért, holott az eddigi hercehurca számlája 100 millió dollár felett jár már.