-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 8 posts ] 
Author Message
 Post subject: many-to-many Mapping füllt Set nicht korrekt
PostPosted: Wed Jun 14, 2006 8:57 am 
Newbie

Joined: Thu May 18, 2006 4:31 am
Posts: 12
Location: Germany
Hallo,

ich habe ein Problem mit dem Lesen von Daten aus einer simplen many-to-many Beziehung.
Diese Beziehung liegt zwischen den Entitäten Benutzer und Kunde. Die Zwischentabelle heißt kunde_benutzer.
(Anmerkung: Dass ein Benutzer mehreren Kunden zugeordnet ist, ist beabsichtigt)

Wenn ich nun Benutzer mit Login "Anton", der zwei Kunden zugeordnet ist (Kunden mit ID 13 und 14), mit Hibernate lade,
bekomme ich zwei Benutzer-Objekte zurück, die jeweils den Login "Anton" haben und jeweils den Kunden mit ID 14!
Ich möchte aber *ein* Benutzer-Objekt haben, dessen Set gefüllt ist mit beiden Kunden.

Kann mir jemand einen Tipp geben, wie ich das richtig mache?

Folgend:
Tabelleninhalte, Hibernate-Mappings, Java-Code, SQL

Hibernate version:
3.1.3


Code:
Kunde:

        ID KUNDEN_NR  NAME
---------- ---------- -------
        14 00009991   Kunde2
        13 00009990   Kunde1



Benutzer:

        ID LOGIN   
---------- --------
        44 Anton


kunde_benutzer:

BENUTZER_ID   KUNDE_ID
----------- ----------
         44         14
         44         13




Mapping documents:
Code:
Mapping für Benutzer:

<class name="Benutzer"
       table="Benutzer">
        ...
        <set
            name="kunden"
            table="kunde_benutzer"
            lazy="true"
            inverse="true"
            cascade="none"
            sort="natural"
        >

          <key column="benutzer_id"></key>
 
          <many-to-many
              class="Kunde"
              column="kunde_id"
              outer-join="auto"
           />

        </set>
        ...
       
Mapping für Kunde:
<class name="Kunde"
       table="Kunde">
        <set
            name="benutzer"
            table="kunde_benutzer"
            lazy="true"
            cascade="save-update"
            sort="natural"
        >

            <key column="kunde_id"></key>

            <many-to-many
                class="Benutzer"
                column="benutzer_id"
                outer-join="auto"
             />
        </set>



Der relevante Java-Code:

Code:
//Zugriff auf Benutzer:
public Benutzer findBenutzerByLogin(String login) {
  String queryString = "FROM Benutzer ben JOIN FETCH ben.kunden WHERE ben.login = :login";
  List<Benutzer> benutzer = (List<Benutzer>) 
        HibernateUtil.getCurrentSession().createQuery(queryString).setString("login", login).list();
  System.out.println("Anz. Benutzer: " + benutzer.size());                          //ergibt 2
  System.out.println("Anz. Kunden Ben(0): " + benutzer.get(0).getKunden().size());  //ergibt 1
  System.out.println(benutzer.get(0));
  return benutzer.get(0);
}

public class Benutzer implements Comparable{
  ...
  public SortedSet<Kunde> getKunden() {
    return this.kunden;
  }
}

public class Benutzer implements Comparable{
  ...
  public SortedSet<Benutzer> getBenutzer() {
    return this.benutzer;
  }
}


The generated SQL (show_sql=true):
Code:
select benutzer0_.id as id1155_0_, kunde2_.id as id1153_1_, benutzer0_.login as login1155_0_, benutzer0_.nachname as nachname1155_0_, benutzer0_.vorname as vorname1155_0_, benutzer0_.passwort as passwort1155_0_, benutzer0_.anlage as anlage1155_0_, kunde2_.anlage as anlage1153_1_, kunde2_.kunden_nr as kunden3_1153_1_, kunde2_.name as name1153_1_, kunden1_.benutzer_id as benutzer2_0__, kunden1_.kunde_id as kunde1_0__ from Benutzer benutzer0_, kunde_benutzer kunden1_, Kunde kunde2_ where benutzer0_.id=kunden1_.benutzer_id and kunden1_.kunde_id=kunde2_.id and benutzer0_.login=?


Top
 Profile  
 
 Post subject:
PostPosted: Wed Jun 14, 2006 9:35 am 
Beginner
Beginner

Joined: Fri May 19, 2006 11:34 am
Posts: 29
Tach,

lass mal in der many-to-many das outer-join="auto" weg...

Ist eigentlich automatisch auf auto, oder hast du einen Eintrag hibernate.use_outer_join in deiner hibernate.cfg.cml?


Top
 Profile  
 
 Post subject:
PostPosted: Wed Jun 14, 2006 10:57 am 
Newbie

Joined: Thu May 18, 2006 4:31 am
Posts: 12
Location: Germany
Hallo,

der Tipp hat leider nicht geholfen.
Ein Ändern von outer-join auf true oder false hat keine Änderung gebracht.
Global habe ich outer-join nicht gesetzt.
In Beispielen sehe ich immer nur die many-to-many-Beziehung, nie den entspr. Hibernate-Zugriff in Java dazu, durch den die Collections entspr. gefüllt werden :(

Jan


Top
 Profile  
 
 Post subject:
PostPosted: Wed Jun 14, 2006 11:11 am 
Beginner
Beginner

Joined: Fri May 19, 2006 11:34 am
Posts: 29
Dann macht mich noch die Abfrage stutzig:
String queryString = "FROM Benutzer ben JOIN FETCH ben.kunden WHERE ben.login = :login";

Du wählst doch das Objekt Benutzer aus. Warum dann da noch mal ein fetch zu den Kunden?? Reicht nicht:

String queryString = "FROM Benutzer ben WHERE ben.login = :login";


Top
 Profile  
 
 Post subject:
PostPosted: Wed Jun 14, 2006 1:03 pm 
Newbie

Joined: Thu May 18, 2006 4:31 am
Posts: 12
Location: Germany
Hi!

AlRudi wrote:
String queryString = "FROM Benutzer ben WHERE ben.login = :login";


Guter Einwand. So habe ich es auch probiert. Vorher noch lazy="false" für die Beziehung Benutzer=>Kunde gesetzt.
Das Ergebnis ist diesesmal:
Ein Benutzer-Objekt (statt zuvor 2), aber auch nur mit einem Kunden in der Menge.

Ich habe mir mal die Hibernate-DEBUG-Ausgaben angeschaut. Er holt sich jedenfalls die beiden Kunden-Objekte, die ich haben möchte, aus der DB. Aber die finden sich irgendwie nicht im Set wieder...

Code:
18:55:23,285 [org.hibernate.pretty.Printer] DEBUG     - listing entities:
18:55:23,289 [org.hibernate.pretty.Printer] DEBUG     - Kunde{anlage=2006-06-12 11:42:44, kundenNr=00009991, name=Kunde2, benutzer=<uninitialized>, id=14}
18:55:23,292 [org.hibernate.pretty.Printer] DEBUG     - Kunde{anlage=2006-06-12 11:42:43, kundenNr=00009990, name=Kunde1, benutzer=<uninitialized>, id=13}

Habe keine Idee...

Jan


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jun 15, 2006 4:09 am 
Newbie

Joined: Thu May 18, 2006 4:31 am
Posts: 12
Location: Germany
Hi,

Das Problem liegt ganz woanders:
Es liegt daran, dass ich ein Set (eine SortedSet, um genauer zu sein) als Collection für die Kunden gewählt habe.
Wenn ich eine List nehme, funktioniert es wie gewünscht.
In einer Set dürfen ja zwei gleiche Elemente nicht vorkommen.

So, ich habe bekomme 2 Kunden-Objekte in einer Liste zurück. Eine neu angelegte Set fülle ich mit diesen beiden Objekten. Anschließend enthält diese Set nur *ein* Element.

Die hashCodes beider Objekte sind verschieden, und ein Vergleich von beiden mit equals() ergibt false. Trotzdem können beide nicht in einer Set vorkommen.

Merkwürdig, ich forsche in diese Richtung weiter...

Gruß
Jan


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jun 15, 2006 4:24 am 
Newbie

Joined: Thu May 18, 2006 4:31 am
Posts: 12
Location: Germany
Oh je,
es lag an einem, naja, Tippfehler in der compareTo-Methode von Kunde:
Code:
  /**
   * Sortierung nach Kunden-Nummer
   * @see java.lang.Comparable#compareTo(T)
   */
  public int compareTo(Kunde o) {
    //-1 wenn dieses Objekt kleiner als o ist
    return this.getKundenNr().compareTo(getKundenNr());
  }


Das return-Statement muss natürlich heißen:

return this.getKundenNr().compareTo(o.getKundenNr());

Verrückt, sowas kostet mich einen einen halben Tag...

Gruß
Jan


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jun 16, 2006 4:04 am 
Beginner
Beginner

Joined: Fri May 19, 2006 11:34 am
Posts: 29
;) That's life...

Irgendwas is ja immer.

Viele Grüsse
Kai


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 8 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.