Avatar billede Slettet bruger
14. oktober 2003 - 18:13 Der er 32 kommentarer og
1 løsning

Brug af entety beans.

Jeg anvender JBoss CMP, og har en metode, i en session bean, som gør følgende:

(Der er tale om et system til håndtering af Lasbiler, og dermed køretøjer, der kan være bl.a Forvogne og Hængere):

1: Henter en Collection med alle køretøjer fra "Koeretoej"'s home interface
2: Itererer denne Collection, og søger for hver iteration i home interfacet for bønnen "Forvogn", efter en "Forvogn", hvis fremmednøgle til "Koeretoej" passer til det aktuelle køretøj.

Formålet er, at finde ud af, om det aktuelle køretøj er en forvogn. Et køretøj kan nemlig også være andre ting.

Metoden følger her:

    public Collection showKoeretoej() throws EJBException
    {
        Collection koeretoej = null;
        Collection koeretoejDTOcollention = new ArrayList();   
        KoeretoejDTO currentDTO;
        Koeretoej currentKoeretoej;
       
        try
        {
            Context context = new InitialContext();
           
            KoeretoejHome finder = (KoeretoejHome) PortableRemoteObject.narrow(context.lookup("Koeretoej"), KoeretoejHome.class);
            ForvognHome FVfinder = (ForvognHome) PortableRemoteObject.narrow(context.lookup("Forvogn"), ForvognHome.class);

            koeretoej = finder.findAll();
            Iterator koeretoejIterator = koeretoej.iterator();


            // Iteration af køretøjer           
            while (koeretoejIterator.hasNext())
            {
                currentKoeretoej = (Koeretoej) koeretoejIterator.next();
                currentDTO = new KoeretoejDTO();

                currentDTO.setKoeretoej_Type(new Integer(0)); // Køretøjets type vides ikke endnu
               
                // Er det aktuelle køretøj en forvogn?
                if (FVfinder.findKT_ID(currentKoeretoej.getKoeretoej_ID()) != null)
               
    currentDTO.setKoeretoej_Type(new Integer(1)); // sæt "Type" til 1, da dette køretøj er en forvogn
                           
                currentDTO.setKoeretoej_ID(currentKoeretoej.getKoeretoej_ID());
                currentDTO.setKoeretoej_Noter(currentKoeretoej.getKoeretoej_Noter());
                currentDTO.setKoeretoej_For_Aksel_Daektype(currentKoeretoej.getKoeretoej_For_Aksel_Daektype());
                currentDTO.setKoeretoej_Traek_Aksel_Daektype(currentKoeretoej.getKoeretoej_Traek_Aksel_Daektype());
                currentDTO.setKoeretoej_Boogie_Aksel_Daektype(currentKoeretoej.getKoeretoej_Boogie_Aksel_Daektype());
                                               
                koeretoejDTOcollention.add(currentDTO);
   
            }
        }
        catch(Exception e)
        {
            e.getMessage();
        }
               
        return koeretoejDTOcollention;
    }

Problemet:

Hvis jeg i metoden ovenover unlader at kalde "FVfinder.findKT_ID(currentKoeretoej.getKoeretoej_ID())", så får jeg alle poster i databasen returneret fra metoden ovenover. Det er også, hvad jeg vil opnå.

Men i det øjeblik jeg overhovedet kalder "FVfinder.findKT_ID(currentKoeretoej.getKoeretoej_ID())", så returnerer ovenstående metode kun de køretøjer, der har en relateret post i tabellen "Forvogn".

Hvorddan kan et kald til en anden entety bean's home interface lave om på antallet af enety beans, der returneres fra min metode.

Det er selve kaldet, der er problemet. Jeg har prøvet at droppe enhver form for kontrol, og bare skrive linien:

Koeretoj test = FVfinder.findKT_ID(currentKoeretoej.getKoeretoej_ID());

...i min metode.

Før jeg tilføjer linien, får jeg alle poster fra min database returneret, og efter jeg tilføjer linien, får jeg kun en begrænset del af min database returneret.

Er der evt. nogen, der kender til et eksempel, jeg kan se, på en sessionbean metode, der håndterer en hiraktisk relation hvor en ting "hører under" noget andet?
Avatar billede arne_v Ekspert
14. oktober 2003 - 18:29 #1
Jeg forstår ikke spørgsmålet.

Din logik er:

find alle køretøjer
for hver køretøj {
    hvis køretøj er forvogn {
        tilføj til listen
    }
}

listen skal vel kun indeholde dem der er forvogn - eller ?
Avatar billede Slettet bruger
14. oktober 2003 - 18:48 #2
nej... listen skal indeholde alle køretøjer.....

Men den skal for hver køretøj "se efter", om køretøjet er en forvogn.

Dertil skal det siges, at hvis ikke køretøjhet er en forvogn, skal den kigge i nogle andre bønner, efter, om den er noget andet, men det har jeg udeladt i min kode og i dette spørgsmål for at holde det så simplelt som mulig indtil dette problem er løst.

Men altså... den skal returnere alle køretøjer, og sætte et "flag" i DTO'en hvis det er en forvogn.

Men den returnerer kun forvognene.... ikke resten af kørtøjerne. Og det skal den.

Jeg kan få den til at returnere alle køretøjer, hvis jeg udelader linierne:

// Er det aktuelle køretøj en forvogn?
                if (FVfinder.findKT_ID(currentKoeretoej.getKoeretoej_ID()) != null)
               
    currentDTO.setKoeretoej_Type(new Integer(1)); // sæt "Type" til 1, da dette køretøj er en forvogn


... men så sættes "flaget" ikke i DTO'en, som det skal.
Avatar billede Slettet bruger
14. oktober 2003 - 18:50 #3
find alle køretøjer
for hver køretøj
{
    hvis køretøj er en forvogn
    {
        sæt et "flag" i det aktielle DTO
    }
    tilføj til listen uanset om "flaget" blev sat eller ej.
}
Avatar billede arne_v Ekspert
14. oktober 2003 - 18:52 #4
Jo men:
  koeretoejDTOcollention.add(currentDTO);
er jo inden i if !?!?
Avatar billede Slettet bruger
14. oktober 2003 - 18:54 #5
nej.... læg mærke til, at der efter if'en ikke er nogle brackets "{" og "}"

det betyder at kun den linie der, er er umiddelbart efter if'en bliver udført hvis true...
Avatar billede Slettet bruger
14. oktober 2003 - 18:56 #6
currentDTO.setKoeretoej_Type(new Integer(1)); // sæt "Type" til 1, da dette køretøj er en forvogn

kun denne linie bliver udført hvis if'en er sand. Resten udføres uanset hvad.
Avatar billede arne_v Ekspert
14. oktober 2003 - 18:56 #7
Sorry - det havde jeg misset.
Avatar billede arne_v Ekspert
14. oktober 2003 - 18:58 #8
Har du prøvet at check omder komemr en exception.

F.eks. ved at udskifte:

e.getMessage();

med:

e.printStackTrace();

og så kigge i console output ?
Avatar billede Slettet bruger
14. oktober 2003 - 18:58 #9
Også svært at se her på eksperten... ikke lige den pæneste opstilling man får, når man copy/paster.

Jeg er egenlig også interesseret i at vide, om jeg gør det på en fuldstøndig tåbelig måde "in the first place"?
Avatar billede Slettet bruger
14. oktober 2003 - 19:03 #10
Ja... og nu skal du så øre noget, der er endu mere "morsomt":

Hvis jeg laver hele "if' en" om til denne:

if (FVfinder.findKT_ID(currentKoeretoej.getKoeretoej_ID()) != null)
{
      currentDTO.setKoeretoej_Type(new Integer(1));
      System.err.println("Køretøj - forvogn...: " + currentKoeretoej.getKoeretoej_ID());
}
else
{
      System.err.println("Køretøj - ikke forvogn...: " + currentKoeretoej.getKoeretoej_ID());
}


Så nås "else" betingelsen aldrig.... JBoss udskriver alrig den sætning. Sevom, der findes køretøjer i databasen, der burde "tigger" den "else".

Konklusion: hvis jeg skriver flg kode:

FVfinder.findKT_ID(currentKoeretoej.getKoeretoej_ID());

... i min metode, så finder den kun en begrænset del af databasen....
Avatar billede Slettet bruger
14. oktober 2003 - 19:04 #11
"tigger" = "trigger"
Avatar billede arne_v Ekspert
14. oktober 2003 - 19:05 #12
Grundliggende bør det virke.

Der er nogen ting jeg ville gøre anderledes.

Jeg er ikke så glade for de hardcoded 0 og 1 for type.

Man bruger normalt ikke _ i navne i Java.

Jeg undrer mig lidt over tabel strukturen, men det er der sikkert
en grund til.
Avatar billede Slettet bruger
14. oktober 2003 - 19:05 #13
... men jeg burde kunne søge i andre enetety beans' home interfaces, uden at der sker mystiske ting, eller er det forkert, at begynde at søge undt i disse?
Avatar billede arne_v Ekspert
14. oktober 2003 - 19:06 #14
Jeg har en anden hypotese:

FVfinder.findKT_ID(currentKoeretoej.getKoeretoej_ID())

smider en exception.
Avatar billede arne_v Ekspert
14. oktober 2003 - 19:06 #15
Derfor mit 18:58:18 forslag.
Avatar billede arne_v Ekspert
14. oktober 2003 - 19:07 #16
Du bør kunne accesse andre entity beans uden problemer.
Avatar billede Slettet bruger
14. oktober 2003 - 19:08 #17
De underscores er drewi's ansvar... det er ikke med min gode vilje, de metoder er navngivet såddan ;)

Men hvis det _burde_ virke, så vil jeg kæme med det lidt endu. Det er hvert fald rart at vide, at det ikke er fordi at "såddan KAN man ikke gøre med EJB".
Avatar billede arne_v Ekspert
14. oktober 2003 - 19:10 #18
Prøv og få checket om det er en exception.
Avatar billede Slettet bruger
14. oktober 2003 - 19:12 #19
Jammen det gav da også pote:

javax.ejb.ObjectNotFoundException: No such entity!

Men hvorfor griver den en exception!? Kan den ikke bare returnere null.

Hvorddan skal man kunne søge efter, om noget findes, hvis EJB containeren "står af", når det ikke findes?
Avatar billede Slettet bruger
14. oktober 2003 - 19:16 #20
Altså problemet er jo, hvis jeg leder efter en forvogn med "Koeretoej_ID" = 7 og der så ikke findes en såddan.

I dette tilfælde er køretøjet så _ikke_ en forvogn.
Men så smider EJB Containeren denne exception...

Hvorfor begynder den at smide exceptions? Kan jeg ikke få den til at give mig et resultat, som jeg kan teste på, om der blev fundet noget, eller ej?
Avatar billede arne_v Ekspert
14. oktober 2003 - 19:20 #21
Jeg kan se flere løsninger.

Den primitive er en separat try catch omkring lige netop den
sætning.
Avatar billede Slettet bruger
14. oktober 2003 - 19:25 #22
Det er jeg under dødstrusler blevet instrueret på, at man aldrig må gøre...

Så laver man en kode, som man _ved_ vil forårsage exceptions....

Må man det?
Avatar billede arne_v Ekspert
14. oktober 2003 - 19:26 #23
Det er ikke pænt nej.

Men alternativt skal du have ændret i findKT_ID metoden !
Avatar billede Slettet bruger
14. oktober 2003 - 19:31 #24
Det bliver nok det... så m vi se, om jeg slipper levende fra det....

Takker mange gange for din tid! Smider du ikke lige et svar?
Avatar billede arne_v Ekspert
14. oktober 2003 - 19:35 #25
Jeg synes måske heller ikke at du skal gå i production med den try catch,
men du kan jo komme lidt videre med det her kode. Og så kan du bede den
ansvarlige for findKT_ID metoden om at forbedre den (elel rlave en anden
metode som opfylder dit behov). Men du behøver jo ikke sidde og trille
tommelfingre indtil det er på plads.

:-)
Avatar billede arne_v Ekspert
14. oktober 2003 - 19:36 #26
svar
Avatar billede arne_v Ekspert
14. oktober 2003 - 20:22 #27
Nogle løse ideer I kan overveje:

1)  put det hele i en tabel så tabellen matcher det den her bean
    skal returnere og den kan bare bruge findAll uden dikkedarer

2)  afskaf hoved tabellen og put alle oplysninger ud i under tabeller
    så kan den her metode kalde X gange findAll

3)  brug CMR (hvis din makker er ham jeg har hjulpet med CMR så
    er det nok ikke sagen da det driller meget)
Avatar billede Slettet bruger
14. oktober 2003 - 20:44 #28
Okay...  FindKT_TD() metoden returnerede et objekt fra entety beanens Remote interface, hvis der blev fundet noget. Ellers smed serveren en exception.

Så læste jeg flg. i API'en til "FinderException" klassen:

"The ObjectNotFoundException exception is thrown by a finder method to indicate that the specified EJB object does not exist.

Only the finder methods that are declared to return a single EJB object use this exception. This exception should not be thrown by finder methods that return a collection of EJB objects (they should return an empty collection instead)."

Så lavede jeg fintKT_ID metoden om, så den returnerede en collection i stedet (selvom denne collectionaldrig ville blive større end et element).

Nu kan jeg så teste, om denne Collection er tom....

Det løser problemet, men jeg synes stadig det er lidt dårliget, at man ikke kan søge efter ét element, uden at forårsage en exception, når man ikke finder noget.

Bare en lille opfølgning.
Avatar billede Slettet bruger
14. oktober 2003 - 20:46 #29
Der er ham, der er min makker ja. Og vi har givet op overfor CMR nu, da deadline nærmer sig med alt for hurtige skridt.
Avatar billede Slettet bruger
14. oktober 2003 - 20:50 #30
Konstruktionen af tabellerne fremkommer af en mapning fra Objektorienteret analyse og design, som vi har lært. I vores lærebog står der, at når man arver fra en klassse, skal man oprette en ny tabel med de specialiserede attributter, og lade en fremmednøgle relatere til den instans af den overordnede klasse, som det specialiserede objekt repræsenterer.

Om det er rigtigt, eller forkert, skal jeg ikke kunne afgøre. Jeg kan blot sige, at det er det, vi har lært.
Avatar billede arne_v Ekspert
14. oktober 2003 - 20:58 #31
Den collection finder er nok den hurtigste måde at få rettet det
til på.
Avatar billede arne_v Ekspert
14. oktober 2003 - 21:02 #32
Der er 3 måder at mappe Child1 og Child2 som extender Parent til
database tabeller.

1)  3 tabeller

2)  1 tabel med felterne fra Parent + 1 felt med type + felter fra Child1 +
    felter fra Child2 og NULL for irrelevante værdier

3)  2 tabeller en med felter fra Parent + felter fra Child1 og en med
    felter fra Parent + felter fra Child2

#1 er den mest objektorienterede.

Men #2 og #3 er nok nemmere at håndtere i praksis.
Avatar billede Slettet bruger
14. oktober 2003 - 21:43 #33
Det har du ret i. Det kan jeg hvert fald skrive under på lige nu.

Vi har valgt #1. Og det er lidt smertefuldt for os nu.
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester