Anzeige:
Ergebnis 1 bis 14 von 14

Thema: EJB3 1:n-Relationen

  1. #1
    Registrierter Benutzer
    Registriert seit
    29.07.2001
    Ort
    Wien
    Beiträge
    90

    EJB3 1:n-Relationen

    Ich hab mir (in Anlehnung an das Buch "Enterprise Java Beans 3.0") mal eine einfache Testapplikation gebaut. Der gesamte Source findet sich auf http://markus.ocrs.at/2006/12/05/ejb3-proof-of-concept (incl. c#-Democlient)

    Es gibt 2 Entities: eine Cruise und eine Reservation, wobei eine Cruise beliebig viele Reservations haben kann:
    Code:
    @Entity
    public class Reservation implements java.io.Serializable {
            private Cruise        cruise;
    
            @ManyToOne
            @JoinColumn( name = "CRUISE_ID" )
            public Cruise getCruise() {
                    return cruise;
            }
    Code:
    @Entity
    public class Cruise implements java.io.Serializable {
            private Collection        reservations        = new ArrayList();
    
            @OneToMany( mappedBy = "cruise" )
            public Collection getReservations() {
                    return reservations;
            }
    Prinzipiell funktioniert das ja ganz gut, was ich nicht verstehe, ist warum eine Suche nach allen Reservierungen die eine bestimmte Cruise betreffen nicht auf die triviale Art geht:
    Code:
    Collection<Reservation> results = cruise.getReservations();
    Sondern ich das umständlich über ein Query lösen muss (und die Ergebnisse dann wieder in Reservations umcasten muss):
    Code:
            Query query = em.createQuery( "FROM Reservation r WHERE r.cruise.id=:cruiseID" );
            query.setParameter( "cruiseID", cruise.getId() );
            List results = query.getResultList();
    Gibt es dafür irgendeinen Grund, sollte getReservations() gehen und ich bin zu blöd, oder soll das eh nicht gehen (und warum?)?
    Diese Message wurde erstellt mit freundlicher Unterstützung eines frei-
    laufenden Pinguins aus artgerechter Freilandhaltung. Er ist garantiert
    frei von Micro$oft'schen Viren.

  2. #2
    Registrierter Benutzer Avatar von Waxolunist
    Registriert seit
    19.06.2006
    Ort
    Wien
    Beiträge
    485
    Durch die Tags erzeugst du jede Menge Code im Hintergrund. Das ganze wird dann ähnlich einer DB oder wenn im Container so konfiguriert in einer DB gespeichert ist aber nicht sehr durchsichtig. Das kommt auf den Persistence Provider an. Am besten macht sich hier wahrscheinlich Hibernate. Das ist aber eines der Probleme von EJB3. Denn die DB wird dadurch nicht wirklich besser wartbar, du ersparst dir imho nur ein bisschen SQL und schreibst dafür aber vier mal so lang am Javateil. Und wenn was nicht geht, ist es beinahe unmöglich, das zu debuggen, weil es zumeist nur an einer Konfigurationsdatei liegt, wenn es nicht funktioniert.

    Imho solltest du, wenn du nicht unbedingt EJB machen musst, POJOS (Plain Old Java Objects) verwenden, mit einer Anbindung an eine DB als Persistenzschicht (auch DAO genannt). Da wird dann vieles klarer. So machen das auch viele Firmen bei ihren Webapplikationen. Zudem, wenn du diese geschickt aufbaust, erparst du dir viel Programmierarbeit und der Code wird wartbarer und lesbarer.

    Für diese Pojos gibt es auch Codegeneratoren, die dir so viel Arbeit ersparen, dass du dich um die Persistenzschicht nicht mehr kümmern musst. Such einmal nach DAO-Generatoren im Web, die gibts wie Sand am Meer. Wir haben bei uns in der Firma ein paar schon selbst geschrieben.

    PS: Allerdings frage ich mich wie du zu dem Cruise-Object kommst in
    Code:
    Collection<Reservation> results = cruise.getReservations();
    ?
    Geändert von Waxolunist (06-12-2006 um 09:54 Uhr)
    Spezialitäten heute: PLSQL, TSQL, Java (alles mit Webanwendungen), Groovy, Grails, ASP.NET, Javascript, Python, Django
    Straight through, ohne Umwege ans Ziel

  3. #3
    Registrierter Benutzer
    Registriert seit
    29.07.2001
    Ort
    Wien
    Beiträge
    90
    Ich dachte Entitäten in EJB3 sind POJOs

    Naja, das muss leider EJB3 + Hibernate + Hypersonic (oder wie die JBoss-DB da heißen mag) sein. In 2.1 hab ich das seinerzeit mit XDoclet recht gut hinbekommen, aber das geht für EJB3 nicht mehr, und was die Annotations machen ist mir auch manchmal mehr als schleierhaft. Und dokumentiert ist das ganze überhaupt nicht. Das das debuggen so gut wie unmöglich ist ist mir auch schon aufgefallen

    Ich hab eine EJB3-Methode die mir einen Haufen Objekte anlegt. Im WebService hole ich mir dann einfach alle Cruises (findAllCruises()), und iteriere über die Ergebnisse, und mit einem dieser Ergebnisse rufe ich dann findAllReservationsByCruise() auf, das eben entweder einen Query macht (funktioniert), oder von der Cruise die Methode .getReservations() aufruft (liefert nix). Da cruise.getId() ja einen sinnvollen Wert liefert, müsste .getReservations() dies doch eigentlich auch tun, oder?
    Diese Message wurde erstellt mit freundlicher Unterstützung eines frei-
    laufenden Pinguins aus artgerechter Freilandhaltung. Er ist garantiert
    frei von Micro$oft'schen Viren.

  4. #4
    Registrierter Benutzer Avatar von Waxolunist
    Registriert seit
    19.06.2006
    Ort
    Wien
    Beiträge
    485
    Also durch Annotations werden die Classfiles bestimmt nicht wie POJOS kompiliert, ergo nein. (Oder war das eh Ironie? Ich bin in letzter Zeit so Ironieresistent. Liegt wohl am Winter).

    Da die Reservations jedoch noch nicht ins Object Cruise geladen wurden, sondern diese erst von der Persistenzschicht geladen werden müssen mittels eines Querys, liefert dir an dieser Stelle ein getReservations allenfalls eine leere Menge zurück. Das ist wie eine DB-Abfrage, select * from cruises. Dann bekommst du auch noch nicht die Reservations, sondern musst erst noch fragen select * from reservations where cruiseid=argument, also 2 Abfragen machen.

    Imho ist diese EJB3-Spez, das schlimmste was je aus dieser Ecke kam. Alles nur Theorie, schaut was ich kann. Man imitiert eine DB ohne DB aber irgendwie doch mit DB - na auf alle Fälle weiß das niemand so genau - und das ganze mit Java anstatt SQL. Ich frage mich, wie da richtige Abfragen ausschauen könnten, also mit joins, orders, groups etc. Und Performance-mäßig wird das nie eingesetzt werden in relevanten Bereichen.
    Spezialitäten heute: PLSQL, TSQL, Java (alles mit Webanwendungen), Groovy, Grails, ASP.NET, Javascript, Python, Django
    Straight through, ohne Umwege ans Ziel

  5. #5
    Registrierter Benutzer
    Registriert seit
    29.07.2001
    Ort
    Wien
    Beiträge
    90
    Also soweit ich das verstanden habe, werden die Annotations nur als Metainformationen mitkompiliert, d.h. die Entity ist auch mit Annotations als POJO verwendbar, um die ganze Persistenz und so kümmert sich der Application Server der diese Metainformationen verwendet.

    Hurra, ich habs. Bissi deppad, aber was solls. Wenn man vor dem getReservations() die cruise nochmal lädt funktionierts:
    Code:
    Cruise myCruise = em.fetch( Cruise.class, cruise.getId() );
    Collection<Reservations> results = myCruise.getReservations();
    Ich dachte das Klump wäre so intelligent die Dinge selbstständig zu laden. Aber das kanns ja nicht, ist ja doch nur ein POJO

    Anmerkung: Ja, ich kann mir auch nicht vorstellen das das irgendwer freiwillig verwendet um damit Geld zu verdienen (höchstens für Schulungen, aber nicht für Applikationen)
    Diese Message wurde erstellt mit freundlicher Unterstützung eines frei-
    laufenden Pinguins aus artgerechter Freilandhaltung. Er ist garantiert
    frei von Micro$oft'schen Viren.

  6. #6
    Registrierter Benutzer Avatar von Waxolunist
    Registriert seit
    19.06.2006
    Ort
    Wien
    Beiträge
    485
    Ah, klingt logisch. Mit einem Query scheint es also wie einer DB-ähnlich (siehe oben) zu funktionieren und ein fetch lädt das komplette Objekt mit Anhang in den Speicher.

    Was mich interessieren würde, wenn du gerade dabei bist, könntest du da mal eine kleine Zeitmessung zu diesen beiden Methoden machen.

    Sagen wir so, 1000 oder besser 10000 Reservations aus einer Cruise laden - einmal mit Query und einmal mit dem fetch, wie lange die Ausführung dauert. Also einmal wie lange diese Zeilen benötigen:

    Code:
            Query query = em.createQuery( "FROM Reservation r WHERE r.cruise.id=:cruiseID" );
            query.setParameter( "cruiseID", cruise.getId() );
            List results = query.getResultList();
    Und wie lange diese benötigen:

    Code:
    Cruise myCruise = em.fetch( Cruise.class, cruise.getId() );
    Collection<Reservations> results = myCruise.getReservations();
    Biiiittte, würde mich mal brennend interessieren.

    mfg, christian
    Spezialitäten heute: PLSQL, TSQL, Java (alles mit Webanwendungen), Groovy, Grails, ASP.NET, Javascript, Python, Django
    Straight through, ohne Umwege ans Ziel

  7. #7
    Registrierter Benutzer
    Registriert seit
    29.07.2001
    Ort
    Wien
    Beiträge
    90
    Stunden später...

    Also mit dem query braucht er für 100.000 Reservations im Durchschnitt 8.1 Sekunden, und mit dem getReservations braucht er 10.6 Sekunden. Das persistieren der Reservations dauert dafür *ewig* (77 Sekunden). Aber ok, das Hypersonic ist ja auch keine vernünftige Datenbank... (und Java ist per Definition langsam)
    Diese Message wurde erstellt mit freundlicher Unterstützung eines frei-
    laufenden Pinguins aus artgerechter Freilandhaltung. Er ist garantiert
    frei von Micro$oft'schen Viren.

  8. #8
    Registrierter Benutzer Avatar von Waxolunist
    Registriert seit
    19.06.2006
    Ort
    Wien
    Beiträge
    485
    Also gut 25% langsamer + wahrscheinlich mehr Speicher - das ist ok. Trotzdem sind 10 sekunden für eine Abfrage ohne Ausgabe oder sonst etwas heavy.

    Dass das persistieren lange dauert, also 100.000 Datensätze schreiben, da hab ich bei Oracle schon schlimmeres erlebt. Das erschreckt mich weniger.

    Und gut programmiert, finde ich Java seit 1.5 gar nicht mehr langsam. Also eine SWT oder Swinganwendung fühlt sich beinahe schon wie eine native Anwendung an.

    Aber danke für deine Informationen.

    mfg, christian
    Spezialitäten heute: PLSQL, TSQL, Java (alles mit Webanwendungen), Groovy, Grails, ASP.NET, Javascript, Python, Django
    Straight through, ohne Umwege ans Ziel

  9. #9
    Registrierter Benutzer
    Registriert seit
    29.07.2001
    Ort
    Wien
    Beiträge
    90
    Ich finde die 10 Sekunden durchaus auch recht heftig. Vielleicht probiere ich das mal mit einer vernünftigen Datenbank im Hintergrund, wäre interessant wie sich das auswirkt.
    Wobei ich keine Ahnung habe was der JBoss so im Hintergrund noch alles treibt. Und der Rechner ist auch nicht mehr unbedingt der schnellste. Trotzdem glaube ich das ein einfaches "SELECT" ein Zehnerpotenzchen schneller wäre...

    Ich gebs ja zu, Java erweckt in letzter Zeit wirklich nicht mehr den Eindruck das man zwischen 2 Klicks einen Kaffee holen muss. Aber ich mag Java nicht, also muss ich meine Vorurteile bestätigen wo es nur geht
    Diese Message wurde erstellt mit freundlicher Unterstützung eines frei-
    laufenden Pinguins aus artgerechter Freilandhaltung. Er ist garantiert
    frei von Micro$oft'schen Viren.

  10. #10
    Registrierter Benutzer Avatar von mwanaheri
    Registriert seit
    28.10.2003
    Ort
    Bayreuth
    Beiträge
    569
    Zitat Zitat von ComSubVie Beitrag anzeigen
    Aber ich mag Java nicht, also muss ich meine Vorurteile bestätigen wo es nur geht
    Heißer Tipp: Stringvariablen in einer Schleife erzeugen und dann weiter zusammensetzen. Bremst so schön ;-)
    Das Ziel ist das Ziel.

  11. #11
    Registrierter Benutzer Avatar von Waxolunist
    Registriert seit
    19.06.2006
    Ort
    Wien
    Beiträge
    485
    Weißt du was noch bremst?

    while(true);
    Spezialitäten heute: PLSQL, TSQL, Java (alles mit Webanwendungen), Groovy, Grails, ASP.NET, Javascript, Python, Django
    Straight through, ohne Umwege ans Ziel

  12. #12
    Registrierter Benutzer
    Registriert seit
    29.07.2001
    Ort
    Wien
    Beiträge
    90
    Das ist ja einfallslos. Wenn schon, dann 2 Threads und einen Deadlock einbauen
    Diese Message wurde erstellt mit freundlicher Unterstützung eines frei-
    laufenden Pinguins aus artgerechter Freilandhaltung. Er ist garantiert
    frei von Micro$oft'schen Viren.

  13. #13
    vocki72
    Gast

    Eine frage zu Java

    Hallo @ all user,
    ich habe eine Frage zu Java, ich habe mit der Programmiersprache java echt meine schwierigkeiten, wie und wo finde ich Übungsaufgaben zu OOP ???

    Desweiteren habe ich eine Frage:

    wie kann ich mit Java , Daten auslesen, wenn das Verzeichnis bekannt ist wo die informationen drin stecken, ich aber nicht weiss welche endungen die Programme haben???

    besten dank


    volker

  14. #14
    Registrierter Benutzer Avatar von Waxolunist
    Registriert seit
    19.06.2006
    Ort
    Wien
    Beiträge
    485
    Bitte mach dafür einen eigenen Thread auf, dann wird dir eher geholfen.

    Dort kannst du mir dann auch gleich erklären was du mit Programme auslesen meinst.

    Und wenn ich in Google "Java Tutorial" eingebe bekomme ich 52.800.000 Treffer. Da wird wohl eines für dich auch dabei sein.

    Desweiteren solltest du auch immer die Suchfunktion bemühen. Ein paar Threads unter diesem ist der Thread:

    Java Einsteiger,.. womit beginnen?
    http://www.mrunix.de/forums/showthread.php?t=47556

    Da solltest du ebenfalls fündig werden für Einsteiger.

    mfg, christian
    Geändert von Waxolunist (07-12-2006 um 10:39 Uhr)
    Spezialitäten heute: PLSQL, TSQL, Java (alles mit Webanwendungen), Groovy, Grails, ASP.NET, Javascript, Python, Django
    Straight through, ohne Umwege ans Ziel

Lesezeichen

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •