- DIGI kábel TV
- Milyen routert?
- Telekom otthoni szolgáltatások (TV, internet, telefon)
- C# programozás
- Vodafone otthoni szolgáltatások (TV, internet, telefon)
- Kodi és kiegészítői magyar nyelvű online tartalmakhoz (Linux, Windows)
- ASUS routerek
- Hálózati / IP kamera
- Tarr Kft. kábeltv, internet, telefon
- Facebook és Messenger
Új hozzászólás Aktív témák
-
Mukorka
addikt
válasz Aethelstone #6201 üzenetére
Akkor inkább a distinct, a set nem szép.
Igazából itt az a baj hogy egyszerre kéred le egy selectben. Esetleg át lehet írni hogy egy másik select hozza le a kapcsolatokat vagy ahogy nálunk sokan tolják (nem is szép) meghívni a size()-t, amit persze ti kikapcsolattatok azzal az extra annotációval.
[ Szerkesztve ]
Mukor#2214 --- "Ezt nem én gondolom így, EZ EGY TÉNY!"
-
Mukorka
addikt
válasz Aethelstone #6204 üzenetére
Átírtam a választ
Mukor#2214 --- "Ezt nem én gondolom így, EZ EGY TÉNY!"
-
-
Mukorka
addikt
válasz Aethelstone #6206 üzenetére
Ha már úgy is van egy külön nem lazy metódusod erre akkor az jelzi hogy néha előfordul hogy kell minden. Sztem belefér, jobb mint fölöslegesen felhozni minden adatot és aztán hagyni hogy a hibernate fölöslegesen dolgozzon rajta. Igen, ízlés dolga
Kell írni sebesség teszteket rá és el lehet pöcsölni még vele egy csomót
(#6208) Aethelstone: Nem tudom, ritka jól sikerült objektum vagyok =)
[ Szerkesztve ]
Mukor#2214 --- "Ezt nem én gondolom így, EZ EGY TÉNY!"
-
Mukorka
addikt
válasz Aethelstone #6208 üzenetére
Akarom mondani singleton
Mukor#2214 --- "Ezt nem én gondolom így, EZ EGY TÉNY!"
-
Aethelstone
addikt
válasz jetarko #6179 üzenetére
Szóval, hogy az eredeti felvetésre is válaszoljunk.
Abszolúte normális, amit tapasztalsz, Hibernate "jellegzetesség". A Set vagy a DISTINCT használata megoldja a "problémát" (Attól függően, hogy miként kéred le az adatokat)
[ Szerkesztve ]
MI 10T Pro 8/256 , Arsenal FC - Go Gunnarz...
-
WonderCSabo
félisten
Olvasom itt a fórumot erről a Hibarnete-es esetről. Én nem használom a Hibernate-et, de józan paraszti ésszel nézve és némi adatbázis használattal a hátam mögött, kizártnak tartom, hogy ez normális viselkedés. A Set és DISTINCT inkább csak a hiba elfedésének tűnik.
Pl. mi van akkor, ha nem uniqe sorok vannak a db-ben (nem jellemző, de akár lehetne). Akkor hogyan oldod meg, hogy ne legyenek felesleges duplikációk, mert a Set és DISTINCT az igazi duplikációkat kinyírja. -
Aethelstone
addikt
válasz WonderCSabo #6212 üzenetére
Akkor használsz List-et, ami a szükséges és a szükségtelen duplikációkat is kezeli. Aztán majd "kézzel" kiszeded. Semelyik ORM nem tud 100%-os lenni.
Másrészről ez a hivatalos Hibernate álláspont, tehát szándékosan ilyen ez látszólag. A Hibernate sokszor nem úgy viselkedik, mint a tiszta JDBC. Ezekkel együtt kell élni.
Harmarészt miért lennének nem unique sorok? Azt hibás tervezés eredménye lehet max.
[ Szerkesztve ]
MI 10T Pro 8/256 , Arsenal FC - Go Gunnarz...
-
Aethelstone
addikt
válasz Aethelstone #6213 üzenetére
Lejárt a módosítás. Ha nem unique sorok vannak, akkor ott a normalizálás sérül....azt meg a kukába kell vetni ilyenkor.
MI 10T Pro 8/256 , Arsenal FC - Go Gunnarz...
-
Szmeby
tag
válasz Aethelstone #6213 üzenetére
És ezen álláspontjukat nagyon arrogánsan képesek védeni is. Borzasztó lekezelően viselkednek a segítséget kérőkkel, cserébe viszont semmi konstruktívval nem tudnak szolgálni. Persze én vagyok a hülye, hogy a Hibernate fórumon kérek segítséget a Hibernate-tel kapcsolatban.
-
WonderCSabo
félisten
válasz Aethelstone #6214 üzenetére
Nyilván az ID-k eltérhetnek, de azt a java kódban az equals metódus-nak nem kell feltétlenül figyelembe vennie, és akkor máris egyenlő két egyed.
Persze az ilyen dolog is még ki fog bukni normalizáláskor, de egyrészt nem kell minden adatbázisnak x. normálformában lennie, másrészt ez az egyszerű példa is mutatja, hogy nagyon sántít ez a dolog.Én OrmLite-ot használok ORM-ként Android-on, az sosem csinált ilyet. Most rákerestem erre a Hibernate OneToMany duplicates problémára, és mindenhol azt olvastam, hogy rosszul volt használva a cucc.
Én elhiszem hogy ez így működik, mivel nem használtam még Hibernate-et (se semmilyen JPA implementációt), de akkor is nagyon furcsának tartom ezt. Ha esetleg erre van doksitok, ami leírja hogy ez az elvárt működés, az hasznos lenne.
-
Aethelstone
addikt
válasz WonderCSabo #6216 üzenetére
Nos, úgy látom, hogy kezdenek itt keveredni a dolgok. Nyilván valamiféle ID-ben el kell térniük, különben alapvető relációs adatbázis kezelési elvek sérülnek. Ha van egy Szemely táblám, amiben két személy csak a személyi számban tér el, akkor a Hibernate/MySQL szempontjából az két eltérő entitásként lesz "objektumizálva", függetlenül attól, hogy a többi metaadat ugyanolyan koppra. A korábban tárgyalt probléma eddig terjed.
Hogy a Java kódban a személyi számot az equals() metódusnál nem veszem figyelembe, az működhet, de ez ebben az esetben a konkrét adatbázis logika lábbal tiprása és semmi köze az ORM implementációhoz.
Hivatalos doksi nincs erről, legalábbis én nem találtam, de az egyik kolléga korábban említette, hogy a hivatalos Hibernate fórum milyen színvonalú. Ott a Hibernate fejlesztők workaroundként javasolják a DISTINCT és a Set használatát, ami kvázi hivatalos álláspont. Ráadásul mi a 3.x-es Hibernatet használjuk, aminél bőven van újabb is, de különféle okok miatt nem tudunk/akarunk egyelőre upgradeolni.
Ettől függetlenül simán lehet, hogy van ennek a problémának rendes megoldása, de ezt én eleddig nem találtam meg, főleg azért nem, mert éppen ma futottam bele ebbe én is és még nem volt időm bővebben kivesézni
[ Szerkesztve ]
MI 10T Pro 8/256 , Arsenal FC - Go Gunnarz...
-
WonderCSabo
félisten
válasz Aethelstone #6217 üzenetére
OK, azért szerintem jogos a duplikált sor lehetősége, különben a DISTINCT operátor értelmét vesztené, csak ezt akartam mondani.
Az viszont lehet, hogy így objektum-relációs leképezésen nem nagyon lehet használni, ebben valszeg igazad van, elnézést. -
Aethelstone
addikt
válasz WonderCSabo #6218 üzenetére
A DISTINCT-nek akkor van szerintem értelme, hogy a a lekérdezésben egy konkrét mezőt akarsz visszakapni, az idézett problémakörben mondjuk egy nevet, de csak egyszer
Órákat, napokat lehetne beszélni a témáról
MI 10T Pro 8/256 , Arsenal FC - Go Gunnarz...
-
WonderCSabo
félisten
válasz Aethelstone #6219 üzenetére
OK, valóban kezdünk eltérni a témától, sorry.
-
floatr
veterán
válasz Aethelstone #6194 üzenetére
Mondjuk sok támpontom nem volt, csak a kolléga kódja, ő meg égert használt annotációban
-
jetarko
csendes tag
válasz Aethelstone #6190 üzenetére
Köszi a választ, örülök, hogy nem én vagyok ilyen béna, de a google skillemen van mit javítani mert hasonló dolgokat írtam be, de még se találtam stackoverflow-os kérdést erre.
Most magamnak írogatok csak programokat ezért az adatbázis mérete nyilván kicsi, de ha van 1millio rekord akkor az adatok lekérése Set-tel sokkal lassabb mint bármelyik List a beszúrási idő miatt. Vagy az elején teljesen felesleges hatékonysági problémákon gondolkodnom?
Amúgy netes tutorial alapján csináltam dao és service-ket és ahol konkrétan lekérem az így néz ki:
public Team getTeamById(int id) {
Session session = this.sessionFactory.getCurrentSession();
Team t = (Team) session.get(Team.class, new Integer(id));
return t;
}A team entitásban meg ugye csak simán van egy Set<Driver> és aztmondom, hogy getTeamById(1).getDrivers() szóval nem látom hova rakhatnám a distinct-et ezért marad Set.
Vagy dobjam a dao és service osztályt és ilyen namedQuery-ket írjak? -
floatr
veterán
válasz jetarko #6225 üzenetére
Pedig nekem is van hasonló mapping pár, és nem látok benne hibát. Kipróbáltam a saját alkalmazásban átírni a collection-t EAGER-re, de akkor sem csinálta ezt. Azt még esetleg megpróbálhatnád, hogy egy teszt erejéig kiszeded az EAGER-t, és a korábban bemásolt kódrészletet kibővíted így:
public Team getTeamById(int id) {
Session session = this.sessionFactory.getCurrentSession();
Team t = (Team) session.get(Team.class, new Integer(id));
// ha lazy collection, akkor így betölti az elemeit egy második query-ben
t.getDrivers().size();
return t;
}Még esetleg azt tudom elképzelni, hogy dialect-függő a dolog. Én eddig mssql, postres és derby adatbázisokkal használtam, de csak elcseszett join-ok esetében találkoztam hasonlóval.
Annyit még érdemes megfontolni, hogy az EAGER típusú kapcsolatok nagyon oda tudnak vágni az alkalmazásnak, ezért is alapértelmezett a LAZY. Én mindenhol ezt használom, és inkább egy OpenSessionInViewFilter-t teszek a web.xml-be. Oda akkor viszont már kelleni fog tranzakció is meg egyebek.
-
sunnysys
tag
válasz Aethelstone #6181 üzenetére
Köszönöm!
Akkor keresek ilyen irodalmat, mert enélkül csak a saját logikámra támaszkodhatok, ami valószínűleg egy idő után már korlátoltan lesz csak elég.
"Gyorsan haladni? Alapvető szabály, hogy akkor lehet igazán hatékonyan megtanulni programozni, ha van értelmes feladat. Nem telefonregiszter és nem DVD kölcsönző nyilvántartás. Viszont komolyabb, életszagú, szopós feladatok csak éles munkahelyi környezetben szoktak adódni "
Na, de honnan tudhatom, hogy mi az értelmes feladat? Teljesen kezdő vagyok, amíg tanárt nem találok, csak netről, könyvekből tájékozódhatok. Munkahelyi környezet pedig egy jó ideig nem áll majd rendelkezésre, gondolom.
-
Szmeby
tag
válasz jetarko #6225 üzenetére
Duplázódás vagy többszöröződés van?
Most hogy láttam a kódod, előjöttek a régi emlékeim.
Nálam többszöröződés jött elő, az adatszerkezet kicsit más volt, de a lényeg ugyanaz: egy entitásban több (egymástól független) lista eager fetch-csel.A problémám az volt, hogy a listák ugyan kis elemszámúak voltak, de többnyire nem 1 elemet tartalmaztak, hanem 2-6 körül. Ami azt eredményezte, hogy a Hibernate a háttérben megcsinálta ezek Descartes-szorzatát, tehát egy 3 elemű lista megtriplázta a másik lista elemeit. (És a Hibernate szerint ez így normális.)
Esetleg érdemes lehet bekapcsolnod a show_sql kapcsolót, hogy megnézhesd, milyen sql lekérdezést gyárt, és azt külön elpattintva milyen resultsetet kapsz. Ne számíts arra, hogy a Hibernate a háttérben majd megszűri neked a duplikátumokat.
Már jó rég volt, de ha jól emlékszem, végül az lett a megoldás, hogy a listákat külön-külön select töltötte fel. A design nem engedte meg, hogy Settel bohóckodjak.
-
jetarko
csendes tag
Töröltem az EAGER-t, majd módosítottam a fv-t és így jól működik.
Az oké, hogy az EAGER lassabbá teszi az alkalmazást, de ha ezeknek a listáknak a mérete kicsi, akkor gondolom nem számít. MySQL-t használok(#6228) Szmeby: Többszöröződés, jelen esetbe 2 helyett 8 lett a lista mérete.
És ezt a külön Select-et hol kéne megvalósítani? Csináljak olyat, hogy a Driver táblából lekérem azokat a sorokat amiknél a team_id megfelel annak amit keresek?Bekapcsoltam a show_sql-t és ezt a förmedvény-t dobja. Az utolsó sor csak akkor van ha a fv-be beírom a t.getDrivers().size()-t.
[ Szerkesztve ]
-
Szmeby
tag
válasz jetarko #6230 üzenetére
Asszem készült egy olyan service metódus (getFullInitializedById() vagy valami ilyesmi), ami id alapján lekérte az entitást (szigorúan lazy fetch minden mezőre), majd az id-val egyesével legyűjtögette a listákat is és a setterekkel beállította azokat az entitáson. Mindezt beburkolva 1 tranzakcióba.
Megjegyzem, tette mindezt azért, mert állandóan nyitott tranzakció / session nem létezett a programban, mindig csak a service metódusban nyílt, elvégezte a szükséges adatbázis műveleteket majd lezárult. Márpedig lazy fetch esetén a listák nem igazi listák csak proxy objektumok, és amint ráhív az ember gyanútlanul egy ilyenre, miközben nincs mögötte aktív session, a cucc borul, mint annak a rendje.
Persze ha neked mindig van nyitott session-öd, akkor talán nem kell vesződnöd a proxyk igazi listára cserélgetésével.De ezt ne vedd követendő példának, nagyon keveset Hibernate-eztem, és azóta csak felejtettem. Nem tartom magamat hozzáértőnek.
select team0_.id as id1_4_0_, team0_.name as name2_4_0_, team0_.points as points3_4_0_, team0_.price as price4_4_0_, races1_.resultOfTeams_id as resultOf2_4_1_, race2_.id as races_id1_3_1_, race2_.id as id1_1_2_, race2_.date as date2_1_2_, race2_.location as location3_1_2_, resultofdr3_.races_id as races_id1_1_3_, driver4_.id as resultOf2_2_3_, resultofdr3_.resultOfDrivers_ORDER as resultOf3_3_, driver4_.id as id1_0_4_, driver4_.name as name2_0_4_, driver4_.points as points3_0_4_, driver4_.price as price4_0_4_, driver4_.team_id as team_id5_0_4_, users5_.team_id as team_id2_4_5_, user6_.id as users_id1_7_5_, user6_.id as id1_5_6_, user6_.money as money2_5_6_, user6_.name as name3_5_6_, user6_.password as password4_5_6_, user6_.points as points5_5_6_, drivers7_.users_id as users_id1_5_7_, driver8_.id as drivers_2_6_7_, driver8_.id as id1_0_8_, driver8_.name as name2_0_8_, driver8_.points as points3_0_8_, driver8_.price as price4_0_8_, driver8_.team_id as team_id5_0_8_
from TEAM team0_
left outer join RACE_TEAM races1_ on team0_.id=races1_.resultOfTeams_id
left outer join RACE race2_ on races1_.races_id=race2_.id
left outer join RACE_DRIVER resultofdr3_ on race2_.id=resultofdr3_.races_id
left outer join DRIVER driver4_ on resultofdr3_.resultOfDrivers_id=driver4_.id
left outer join USER_TEAM users5_ on team0_.id=users5_.team_id
left outer join USER user6_ on users5_.users_id=user6_.id
left outer join USER_DRIVER drivers7_ on user6_.id=drivers7_.users_id
left outer join DRIVER driver8_ on drivers7_.drivers_id=driver8_.id
where team0_.id=?Ha ezt végrehajtod az adatbázison valamilyen id-val a ? helyén, akkor megnézheted a duplikátumokat. Kis elemszámú listák esetén is nagy resultset képződik ebből.
Az, hogy valami lassú, nem számít. Fontosabb, hogy optimális legyen. Ha teszemazt azonnal szükség van x, y, és z táblákból (összetartozó) adatokra, akkor gyorsabb előállítani azokat egy lekérdezéssel. De ha első körben csak az x-re van szükséged, és fontos a reszponzivitás, akkor y és z ráér később, ajánlott a lazy-re állítani. Az igényektől függ, hogy mi a jó megoldás.
(#6231) jetarko
Szerintem nem. Eagerben minden táblát join-ol és egy lekérdezéssel letudja az adatok elővételét. Lazyben csak a fő entitást veszi elő, majd a size() metódushíváskor aktiválja a proxyt, ami előállít egy újabb selectet, ami a listát tölti fel értelmes adattal. Tehát utóbbi esetben több független lekérdezés pattan.[ Szerkesztve ]
-
floatr
veterán
A filter annyit csinál, hogy egyazon session-t fog visszaadni a request idejére. Ez akkor kellhet, ha lazy collection-öket használsz, de nem inicializálod őket a betöltéskor. Ilyenkor session hibával hanyatt esik az egész.
A tranzakció egy kicsit más, azt definiálhatsz többet is pl. annotációval a business layer-ben. Ha egy controller több business metódust használ, akkor több tranzakció is kifuthat menetközben.
(#6230) jetarko nem lassabb lesz, hanem néha feleslegesen végzi a munkát, több memóriát ehet stb. Amikor EAGER-nek definiálsz egy kapcsolatot, akkor a tulaj betöltése nem egy szimpla select lesz, hanem hozzáfűzi az összes kapcsolatot, és egy menetben tölti be az adatokat.
Amikor a size() metódust használod LAZY-vel, akkor külön SQL fut le a collection-re.Ami duplikálódást illeti, asszem itt már azért látszódik, az oka az egésznek. EAGER az összes kapcsolatod, ezért szépen sorban hozzáfűzi JOIN-nal a TEAM táblához a lekérdezésnél. 1 join esetében a TEAM duplikálódik, minden további join esetében viszont a hozzáfűzött táblák rekordjai is. Itt lehet kutya elásva. Valószínűleg több collection is duplikált adatokat fog tartalmazni emiatt az összesített SQL miatt. Amikor a példámban néztem, nekem csak egy one-to-many kapcsolatom volt, amiben a tulaj szűrve volt, a collection elemei pedig egyszer jöttek a select-ből. Ha több ilyen van, akkor a select egyszerűen ilyen hulladék eredményt ad.
Emiatt is érdemes lenne subselect-eket használni valamilyen módon. Mondom, én a filtert javaslom LAZY-vel
[ Szerkesztve ]
-
floatr
veterán
válasz Aethelstone #6233 üzenetére
JTA vagy sem, ha már Spring-et használ, akkor ott van a @Transactional(propagation=Propagation.SUPPORTS) vagy REQUIRED
-
floatr
veterán
válasz Aethelstone #6236 üzenetére
Ja, hát ez a kézimunka elég nagy marhaság a példákban, pláne hogy mindenki ebből tanulna a zinternetrül. Épp most tépem a hajam, hogy egy olyan projektbe ugrottunk be, amit olyan "szakik" készítettek elő, akik netes példákból ollózták össze a tudásukat.
-
Aethelstone
addikt
-
floatr
veterán
válasz Aethelstone #6238 üzenetére
És egy C/C++ fejlesztő ismerős kérdezte, hogy mi a fenéért nyomják ezeket a tervezési mintákat... hát ezért.
-
floatr
veterán
válasz Aethelstone #6240 üzenetére
Régebben én is szkeptikus voltam, de ahogy látom ahogy hígul a szakma, és kik mondják magukat java fejlesztőnek, neadjaég senior-nak, azóta úgy érzem, hogy az egyik legjobb ötlet volt a minták nyomatása.
-
jetarko
csendes tag
válasz Aethelstone #6238 üzenetére
Valahol el kell kezdeni és mivel suliba ilyet nem tanítanak, ezért első körbe az ilyen netes tutorialokat nézegettem, de azt én is leszűrtem, hogy nem az igaziak, már ha egyáltalán működnek.
Suliba belenéztünk kicsit JPA-ba, de amúgy csak SE volt.
Majd most utána akarok nézni a memory profiling-nak meg az alkalmazás szerverek konfigurálásának, mert az, hogy én localhost-ba elszórakozok egy projectel az oké, de ha ez éles project lenne, akkor gondolom számítana memória használat, skálázhatóság és még nem tudom mik.
Még fél évig suli mellett nem tudok menni melózni, ezért addig marad az itthoni tanulgatás, mert érdekel a java ee világa.És miből lenne érdemes tanulni a netes tutorialok helyett? Álljak neki olvasni az igencsak hosszú hibernate és spring doksit?
Ha már szóba jöttek a design pattern-ek párat mondanátok, amiket érdemes lenne tanulgatni, használni ebben a témában?
-
Lacces
őstag
Hali.
Voltam Androidos előadáson, ami feltűnt nekem, hogy a példa forráskódban minden változó final kulcsszót kapott, ez miért jó? Hiszen ha egy List is final, utána ugyanúgy lehetett a List-be elemeket tenni.
-
nagyúr
> Hiszen ha egy List is final, utána ugyanúgy lehetett a List-be elemeket tenni.
Jo meglatas - ami neked feltunt, az a 'constness', vagy immutabilitas koncepciojanak a (majdnem teljes) hianya a Java-ban. Az altalanos immutabilitas igazan hasznos lehetne, konkurens programozasnal (is) egy aldas, meg egyebkent is sokkal atlathatobb, bugmentesebb kodot lehet irni akkor, ha az ember ahol csak lehet, 'ertekkel' es nem 'identitassal' dolgozik.
while (!sleep) sheep++;
Új hozzászólás Aktív témák
A topicot kiemeltem. Valaki nem akar egy nyitó hsz-t írni?:))
Állásajánlatok
Cég: Ozeki Kft.
Város: Debrecen