Hejsan! Hej, Intressant fråga.. Använder inte något framework likt Hibernate, Castor, JDO eller liknande. Allt är helt och hållet utvecklat under J2SDK 1.4.1. Lazy loading svarar inte mot mina behov just i detta avseende. Används i andra delar av applikationen dock ;-) Hej!! Tack för det tipset! Hej OK! Helt rätt Håkan! Även Ni med Walle... låt mig förklara vidare. Hej Använder numera ett persistency framework kallat Hibernate. Ah, nice... Relationer i Java - Objekt-/relationsmappning
Skulle behöva förslag och råd på hur man kan mappa en flera till flera relation i en databasmodell till Java.
Om Class_A har en lista med referenser till Class_B, och Class_B har en lista med referenser till Class_A är ju relationen realiserad, eller hur?
Problemet uppstår när man ska ladda upp en flera poster ur en tabell, skapa sina databärare (ValueObjects/TransferObjects) med en lista av objektreferenser till andra objekt. Det blir en oönskad effekt eftersom samma instans återkommer gång på gång, vilket inte är önskvärt.
Scenario:
Class_A_1 laddar en lista med relaterade objekt från databasen, säg Class_B_1 och Class_B_2 (siffran representerar olika instanser, d.v.s. olika rader i tabellen).
Class_A_2 laddar en lista med relaterade objekt från databsen, här ingår också posten Class_B_2 p.g.a. ett många till många förhållande.
Vips så har vi dubbla instanser som representerar samma post i databasen på två olika ställen! Önskvärt vore om samma instans som representerar en rad i databasen förekom i Class_A_1 resp. Class_A_2.
Mer beskrivande:
Antag en relation mellan tabellen person och adress. En person kan ha flera adresser (företag/privat) och en adress kan tillhöra flera personer (en hel familj).
1. Objekt_Person_Kalle laddar från databasen de adresser som är relaterade till honom, säg Objekt_Adress_Privat och Objekt_Adress_Företag
2. Varje adress mappas som ett objekt i applikationen, d.v.s. när vi laddar upp datat från adress databasen skapar vi en databärare som innehåller detta data (ValueObject)
3. Objekt_Persson_Lisa laddar från databasen de adresser som är relaterade till henne, som Kalles sambo har hon också en referens till samma Objekt_Adress_Privat som Kalle.
4. En ny instans skapas med datat hämtat från databasen.
Nu har vi två olika instanser som ska representera samma sak deklarerat i två olika objekt.
5. Kalle ändrar sin privata adress eftersom Lisa och Kalle ska flytta till hus.
6. Instansen Objekt_Adress_Privat hos Kalle ändras, men inte hos Lisa eftersom de äger två olika instanser av samma objekt!!!
Nu är objektmodellen inkonsistent och det kommer att uppstå konstiga problem om både Kalle och Lisa fortsätter att använda systemet i samma session.
Förslag och designtips uppskattas!
Mvh, AndreasSv: Relationer i Java - Objekt-/relationsmappning
Vad arbetar du med för arkitektur vad gäller persistens/datalager? Du använder dig inte av EJBs eller något objekt/relation persistens ramverk som t ex Hibernate?
/KlasSv: Relationer i Java - Objekt-/relationsmappning
Jag har inget direkt svar på det men om du använder lazy load så minskar du risken att få objekten i osynk. Nu vet jag inte om detta fungerar i din applikation.. Men skapa ett proxyobjekt för adressen som håller pk för den aktuella posten och ladda den endast vid behov..
Som sagt detta är nog ingen lösning på ditt problem, men berätta gära hur du löste det när du löst det :)
Hibernate verkar väldigt nice och man kan bara hoppas på att nhibernate blir klart någon gång.. Sv: Relationer i Java - Objekt-/relationsmappning
Oftast så innebär dessa framework att man ska använda JNDI vilket inte är möjligt i mitt fall p.g.a. företagspolicys, tyvärr! :-/
Arkitekturen bygger på en tilltänkt 3-skiktsarkitektur, fast utvecklat som 2-skiktsarkitektur (konstigt va?) ;-)
Kort och gott... vi bygger i lager fast utan en applikationsserver just p.g.a. att migrering till en J2EE-arkitektur ska vara möjlig i framtiden.
/AndreasSv: Relationer i Java - Objekt-/relationsmappning
/AndreasSv: Relationer i Java - Objekt-/relationsmappning
Undrar om inte ett designpattern känt som "Singleton" skulle passa här.
Du kan då bara instansiera ett objekt åt gången, alla andra får vänta.
För mer info om Sinleton:
http://www.javaworld.com/javaworld/jw-04-2003/jw-0425-designpatterns.html?
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnbda/html/singletondespatt.asp
http://gnump3d.sourceforge.net/singleton.html
/HåkanSv: Relationer i Java - Objekt-/relationsmappning
Singleton används i systemet, men är inte applicerbart i detta fall. Ett ValueObject vill ju kunna representera flera olika instanser (rader i tabellen) och bör därför inte vara designat som en singleton.
Tack ändå!
Mvh, AndreasSv: Relationer i Java - Objekt-/relationsmappning
Finns det möjlighet att få lite mer info om hur det hela är uppbyggt?
En möjlig lösning skulle kunna vara en datacache...
Då Objekt_Person_Kalle laddar adresserna så laddas de från databasen och läggs i din cache i datalagert. Då sedan, Objekt_Persson_Lisa laddar adresserna så kontrolleras det om dessa objekt finns i cachen som är implementerad som en singelton. Finns det laddat så hämtas det från cachen. Eftersom som du vet att du kan få detta problemet med olika värden med dina databärare så implementerar du någon light variant av lazy load så att man alltid hämtar datan från cachen eller direkt från databasen.
Kruxet är om du vill visa information för både lisa och kalle samtidigt och att du vill återspegla förändringarna direkt, men då kan man kanske låta en eventuell kontroller ta hand om denna uppdatering.
Men jag vet inte om jag förstår problemet på rätt sätt.. Sv: Relationer i Java - Objekt-/relationsmappning
Tror att jag förstår lite mer hur det "fungerar".
Ett ValueObjectär är ett (generellt) objekt som innehåller poster (tuples) från databasen.
Dessa kan instansieras obegränsat, då de innehåller (normalt sett) olika poster från databasen.
Problemet: att de kan innehålla samma poster!
Ungefär så??
/HåkanSv: Relationer i Java - Objekt-/relationsmappning
Jag ska försöka göra en liknelse med ett annat system:
Vi har ett enkelt ordersystem där vi registrerar kunder, ordrar och produkter. I detta system har vi ingen central server som affärslogiken exekveras på utan vardera försäljare har sin egen applikation som pratar mot en central databas. Detta system ska vara designat på ett smart sätt så att det kan på ett enkelt sätt "lyftas över" till en arkitektur på J2EE.
En order kan ju innehålla flera produkter, och en viss produkt kan finnas med i flera olika ordrar. Då har vi en flera till flera relation som måste lösas på ett bra sätt.
Antag att en försäljare vill hämta upp två ordrar som tillhör en och samma kund för att modifiera dem lite utifrån kundens önskemål. När denna order laddas så ska order instansen innehålla en lista med objektreferenser till de produkt instanser som ingår i ordern. Likaså ska den aktuella produkt instansen innehålla en lista med objektreferenser till de ordrar som just denna produkt tillhör. Om nu våra två olika ordrar skulle innehålla en och samma produkt så innebär det att vi skapar två instanser av samma produkt klass när vi laddar våra två ordrar. Ändrar vi i tillståndet för denna produkt i en av ordrarna (säg att en produkt ska i årets modell vara gul) så ändras det bara i instansen hos den ena ordern och inte den andra.
Detta skulle kunna lösas med ett objekt cache, jag håller med. Ett problem återstår dock; vem ska vara ansvarig för att relationen hålls? I databasmodellen får vi ju en relationstabell mellan tabellen ordrar och produkter för att realisera ett flera till flera förhållande. Ska affärsobjektet som opererar på ordrar skriva till relationstabellen eller ska affärsobjektet som opererar på produkter skriva till relationstabellen? Säg att en produkts tillstånd har ändrats och flaggs som "dirty". Lägger vi logiken hos kontrollern för produkterna så måste den ta reda på om det finns en rad med det order id som den är relaterad till. Kolla om denna produkt är den som är relaterad till denna order (i kopplingstabellen) och i sådana fall uppdatera raden. Om denna rad inte finns så ska kontrollern skriva dit en ny rad. *pust* Bökigt!!!! Nu är detta ett enkelt exempel... läs vidare för att se hur det är mer i systemet.
Affärsobjektet är en kontroller som svarar för sin lilla domän. Ex: OrderController ansvarar för order objekt och operationer som ladda order från databas, spara order till databas, ta bort order från databas etc. Eftersom en order innehåller produkter så kan vi säga att ett order objekt är ett komplext ValueObject som innehåller ValueObject som representerar produkter, eller hur? Så det finns även en ProductController som fungerar på samma sätt som OrderController.
När vi laddar en order skes ett anrop till OrderController:loadOrder(String orderId) som i sin tur anropar ProductController:loadProductsRelatedToOrder(String orderId, Order relatedOrder). Det är byggt på detta sätt med delegering för att seperera så mycket som möjligt.
Nu låter detta som ett enkelt problem att lösa, men verkligheten är så här:
Säg att det är ett stort ordersystem där en försäljare kan operera på flera ordrar, och där försäljaren även kan vara en leverantör av flera av produkterna som säljs! Då har vi att en order har följande relationssemantik...
Order M -- N Produkt En order kan innehålla flera olika produkter
Order M -- N Försäljare En order kan bli skött av flera olika försäljare
Försäljare M -- N Produkt En försäljare som även är leverantör kan vara det för flera olika produkter
Nu har vi ett cirkulärt förhållande mellan order, produkt och försäljare/leverantör. I princip kan vi säga att det också finns tre olika affärsobjekt (kontrollers) för dessa entiteter. Sådana här relationer finns det mycket av i systemet...
Detta är något som jag skulle vilja ha ett schysst framework över eller ett bra designtips för att hantera!
Hoppas att Ni är med på noterna ;-)
Mvh, AndreasSv: Relationer i Java - Objekt-/relationsmappning
Hur gick det med detta problemet, hittade du någon snitsig lösning på det?Sv: Relationer i Java - Objekt-/relationsmappning
Det fungerar mycket bra!
Mvh, AndreasSv: Relationer i Java - Objekt-/relationsmappning
Har kikat på Hibernate och det verkar ruggigt trevligt.. Riktigt synd att de lade ner nhibernate, som skulle bli en .net version av Hibernate.