Øving 11 - del b Oppgave 1 fasade av Session Beans. Denne oppgaven kan også gjøres samtidig som oppgave 2 (det er imidlertid enklere å holde oversikten om du gjør en ting i gangen). Du skal nå lage en fasade ( med en Session Bean) til EJB en du lagde i oppgave 1. Lag løsningen din slik at klienten aldri har direkte kontakt med Entity EJB en. Klienten skal fortsatt ha tilgang til de samme metodene som før, men nå via fasaden. Merk at det vil være naturlig å bruke verdiobjekter i dette tilfellet. Her er et tenkt scenario som beskriver dette: 1. Klienten kaller metoden hentallepersoner() på Session Bean fasaden. 2. Session EJB en bruker så Entity EJB en for å få tak i alle personene. 3. Da klienten ikke skal ha direkte kontakt med Entity EJB en så returnerer Session EJB en verdiobjekter tilbake til klienten. Klassen kan f.eks. hete PersonVO, og inneholder de verdiene som er interessant for klienten (husk at objektene må være serialiserbare). 4. Klienten mottar verdiobjektene, og kan vise innholdet i disse. Ved oppretting av en ny person vil tankegangen være den samme. Klienten oppretter et PersonVO-objekt som sendes til fasaden. Her blir verdiene hentet ut og nødvendige kall på Entity EJB en blir gjort. Relasjoner mellom Enity Beans Fram til nå har vi hatt databasetabellen konto, hvor vi hadde feltene kontonr, fornavn, etternavn og saldo. Dette er ikke en god løsning fordi en person kan ha flere kontoer. Hvis så er tilfellet, blir personens fornavn og etternavn lagret flere ganger i databasen (og dette ønsker vi ikke). For å unngå dette problemet bruker vi heller to databasetabeller. La oss først se på problemet med objektorientert tankegang. Se figuren under. Person 1 * Konto Av figuren kan vi lese at en person har 0 eller flere kontoer. Merk at en konto ikke kan ha flere eiere (det er bare noe jeg har bestemt i dette tilfellet). Det beste vil nå være å lage to databasetabeller som vist under: Tabellen Person kan se slik ut: Personnummer Fornavn Etternavn 231288 45254 Ola Normann
010199 11111 Kari Normann Tabellen for Konto kan se slik ut: Kontonr Saldo Fremmednøkkel 1 1000 231288 45254 2 2000 231288 45254 3 1 010199 11111 Vi ser at tabellen Konto vil inneholde en fremmednøkkel til tabellen Person. Vi knytter på denne måten en Konto opp mot en Person. Du kan også se av tabellen over at Ola har to kontoer. Bruker vi Entity Beans med BMP, så må vi selv sørge for å opprette disse tabellene og skrive koden for å manipulerer dem. Når vi bruker CMP skal vi imidlertid ikke skrive databasekode. Det er imidlertid nødvendig å beskrive forholdet mellom slike CMP EJB er. Dette fordi det er containeren sin oppgave å lage databasen (vi kan også gjøre det manuelt selv), men containeren kan ikke i utgangspunktet vite om hvor mange kontoer en person kan ha. For containeren er det like naturlig at en konto kan ha flere eiere. I dette tilfellet blir databasetabellene annerledes (det holder ikke lenger med en fremmednøkkel i tabellen Konto). Det jeg prøver å si er at du selv må spesifisere forholdet (relasjonene) mellom CMP EJB ene. For at dette skal fungere så må EJB ene ha lokale-interface. De må også ligge i samme jar-fil. Forholdet mellom EJB ene beskrives i deploytool (kommer tilbake til dette). Når vi lager løsningen vår så bryr vi oss ikke om hvordan databasen ser ut. Dette er helt og holdent opp til containeren. For oss vil en person ha 0 eller flere kontoer. I PersonBeanklassen vil det derfor være naturlig å ha en Collection som inneholder referansen til de Konto EJB er. Vi må utvide med følgende get/set-metoder i PersonBean: public abstract Collection getkontoer(); public abstract void setkontoer(collection kontoer); I deploytool så vil kontoer nå vises sammen med de andre feltene (egenskapene) til en person (fornavn, etternavn, personnr). Dette er vist i figuren under. Merk at kontoer ikke er merket av for å bli varig lagret (persisted). Grunnen til dette er at kontoene er EJB er og er derfor i seg selv varige. Containeren vil nå kun sørge for at referansene til disse EJB ene blir tatt vare på, slik at vi kan finne kontoene senere.
Nå må vi beskrive forholdet mellom Entity EJB ene KontoBean og PersonBean. Velg jar-filene komponentene ligger i, og skillearket Relationships. Ved å velge Add kan du nå beskrive forholdet mellom Entity EJB ene. Du får da opp et nytt skjermbilde (se under). Her velger vi: Multiplicity (Bean A : Bean B). I vårt tilfelle vil det være One to Many (en person kan ha flere kontoer).
Så velger vi hvilken av EJB ene som skal være EJB A og hvilken som skal være EJB B. Her blir A PersonBean og vi velger derfor dette i Enterprise Bean Name. Så velger vi hvilket felt i PersonBean som inneholder referanser til EJB B. Hos oss er det kontoer. Dette er en Collection som inneholder kontoene til personen. Typen er java.util.collection. For EJB B, velger vi KontoBean. En konto vet ikke hvem eieren er (om dette er et problem så bør vi lage løsningen slik at også konto har en referanse til person). Vi velger derfor <none> i Field Referencing Bean A. Tilslutt krysser jeg av for Delete When Bean A is Deleted. Mao. når en person slettes så vil også kontoene hans slettes. Grunnen til dette er at en konto ikke kan eksistere uten en eier. Trykk OK. Skjermbildet blir nå slik:
Da har vi beskrevet forholdet mellom de to Entity EJB ene. Containeren vil nå sørge for å vedlikeholde relasjonene. Det vil nå være naturlig å ha en metode i PersonBean som registrerer en konto til personen. F.eks. kan metoden bli slik: public void leggtilkonto(kontolocal konto){ Collection kontoene = getkontoer(); //henter kontoene til personen kontoene.add(konto); // legger til en konto setkonto(kontoene); // lagrer kontoene } Legg merke til at vi bruker getkonto() til å finne alle kontoene som personen har. For å endre kontoene til en person kaller vi setkonto(). Oppgave 2 I forrige oppgave lagde du en CMP PersonBean. For denne EJB en lagde du også en fasade. Du skal nå utvide denne løsningen (for de som ikke har gjort forrige oppgave, ta kontakt for å få løsningsforslaget). Løsningen din skal ha Entity EJB ene KontoBean og PersonBean. Merk at i KontoBean skal det kun lagres kontonr og saldo (ikke fornavn og etternavn). En konto må ha en eier og til dette bruker vi PersonBean. Du må derfor spesifisere relasjonen mellom disse to EJB ene (se kapitlet om relasjoner). I tillegg så skal du utvide fasaden slik at det er mulig å finne kontoene til en person. Det skal også være mulig å overføre penger mellom to kontoer (ikke nødvendigvis eid av samme person). Blant a public void overfør(...) // overføring mellom to kontoer public double hentsaldo(...) //hent saldo til en gitt konto public Collection hentallekontoerforperson(...) //henter kontoene til en person
public void slettperson(...) //sletter en person, kontoene skal også slettes public void opprettperson(...) //oppretter en ny person public void leggtilkontotilperson(...) //legger til en konto til en person Tilslutt beskriv hva du må gjøre for å være sikker på at transaksjonen overfør(..) blir riktig.