-->
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.  [ 10 posts ] 
Author Message
 Post subject: Laden von Collections eines Objektes
PostPosted: Mon Jan 26, 2009 1:17 pm 
Newbie

Joined: Fri Jan 23, 2009 2:32 pm
Posts: 7
hallo
Ich habe zwei Klassen member und teams. Ein member kann in mehreren teams sein, und ein team hat mehrere memer. Das Mapping sieht wie folgt aus:

team.hbm.xml
Code:
<class name="Team" table="TEAMS">
     <id name="id" column="TEAM_ID">
        <generator class="native"></generator>
     </id>
     <property name="teamName" column="NAME"></property>
     <property name="playedGames" column="PLAYED_GAMES"/>
     <set name="members"
        table="TEAM_MEMBERS"
      cascade="save-update"
      lazy="false"
      >
      <key column="TEAM_ID"/>
      <many-to-many class="Member" column="MEMBER_ID"/>
   </set>
  </class>


member.hbm.xml
Code:
<class name="Member" table="MEMBERS">
     <id name="id" column="MEMBER_ID" >
        <generator class="native"></generator>
     </id>
     <property name="email" column="EMAIL"></property>
     <property name="lastname" column="LASTNAME"></property>
     <property name="surname" column="SURNAME"></property>
     <property name="username" column="USERNAME" not-null="true"></property>
     <property name="password" column="PASSWORD" not-null="true"></property>

   <many-to-one
          name="homeAdress"
          column="HOME_ADRESS"
      class="ch.hotmilk.jadezu.model.Adress"
      cascade="save-update"
      unique="true"
      lazy="false"/>
      
   <property name="isAdmin" column="IS_ADMIN" />
   <property name="isSystemAdmin" column="IS_SYS_ADMIN" />

  </class>


Das Problem ist jetzt, dass wenn ich ein team von der Datenbank hole, das Set indem die member gehalten werden null ist. Sollte es nicht so sein, dass Hibernate hier auch diese Objekte laden sollte? Oder dass ein Proxy geladen wird und dann beim ersten aufruf der member diese dann geladen werden?

Falls ihr noch mehr angaben braucht, dann sagt es mir.

Vielen Dank im Voraus und
gruess
stephan


Top
 Profile  
 
 Post subject:
PostPosted: Mon Jan 26, 2009 5:35 pm 
Senior
Senior

Joined: Thu Jan 08, 2009 3:48 pm
Posts: 168
Grundsätzlich sollte das set durch lazy=false mit geladen werden, das hängt aber von der Art und Weise ab wie Du die Daten lädst:

- mit get, load oder einer Criteria Query sollte das Set mitkommen
- mit HQL oder SQL nicht

Wie greifst Du derzeit auf das Team zu?


Top
 Profile  
 
 Post subject:
PostPosted: Tue Jan 27, 2009 3:54 am 
Newbie

Joined: Fri Jan 23, 2009 2:32 pm
Posts: 7
Ich habe es auf zwei verschiedene arten probiert. das eine ist mit session.createCriteria(), die andere ist session.load(). Bei beiden wird mir ein Team-Objekt zurueckgegeben, jedoch ist immer das Set leer.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Jan 27, 2009 4:00 am 
Senior
Senior

Joined: Thu Jan 08, 2009 3:48 pm
Posts: 168
Poste mal Deinen Code, die generierten SQLs und den Inhalt der Datenbank für die verwendeten IDs.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Jan 27, 2009 1:07 pm 
Newbie

Joined: Fri Jan 23, 2009 2:32 pm
Posts: 7
Hallo

Inhalt der Datenbank:

Tabelle "Teams":
TEAM_ID 4
NAME: team1
PLAYED_GAMES 0

Tabelle "Team_Members":
TEAM_ID 4
MEMBER_ID 5
---
TEAM_ID 4
MEMBER_ID 10

Tabelle "Members":
MEMBER_ID 5
EMAIL member2@hotmilk.ch
USERNAME member2
---
MEMBER_ID 10
EMAIL member4@hotmilk.ch
USERNAME member4



Der code sieht folgendermassen aus:
Code:
   public T findById(ID id, boolean lock) {
        T entity;
        if (lock) {
            entity = (T) getSession().load(getPersistentClass(), id,
                    LockMode.UPGRADE);
        } else {
            entity = (T) getSession().load(getPersistentClass(), id);
        }
        return entity;
    }

Der Code geht ins else, getPersistentClass() gibt "ch.hotmilk.jadezu.model.Team" zurueck. Bei der ID uebergebe ich 4L.

Hier wird nur die Klasse Team instanziert. Wenn ich dananch team.getMembers() aufrufe:

Code:
Hibernate:
    select
        team0_.TEAM_ID as TEAM1_1_0_,
        team0_.NAME as NAME1_0_,
        team0_.PLAYED_GAMES as PLAYED3_1_0_
    from
        TEAMS team0_
    where
        team0_.TEAM_ID=?
Jan 27, 2009 5:45:43 PM ch.hotmilk.jadezu.model.Team <init>
INFO: Class instaniated
Hibernate:
    select
        members0_.TEAM_ID as TEAM1_1_,
        members0_.MEMBER_ID as MEMBER2_1_,
        member1_.MEMBER_ID as MEMBER1_0_0_,
        member1_.EMAIL as EMAIL0_0_,
        member1_.LASTNAME as LASTNAME0_0_,
        member1_.SURNAME as SURNAME0_0_,
        member1_.USERNAME as USERNAME0_0_,
        member1_.PASSWORD as PASSWORD0_0_,
        member1_.HOME_ADRESS as HOME7_0_0_,
        member1_.IS_ADMIN as IS8_0_0_,
        member1_.IS_SYS_ADMIN as IS9_0_0_
    from
        TEAM_MEMBERS members0_
    left outer join
        MEMBERS member1_
            on members0_.MEMBER_ID=member1_.MEMBER_ID
    where
        members0_.TEAM_ID=?

Die Member Collection in der Klasse Team ist nicht "null", sondern leer, es hat einfach keine Objekte drin.
Vielen Dank schon mal fuer deine Muehe.

gruess
stephan


Top
 Profile  
 
 Post subject:
PostPosted: Tue Jan 27, 2009 4:15 pm 
Senior
Senior

Joined: Thu Jan 08, 2009 3:48 pm
Posts: 168
Step by step:
- Team ist sicher geladen, dh Du kannst zB Name ausgeben?
- Team.getId() retourniert 4?
- Wenn Du das SQL kopierst und direkt ausführst (DB Client) mit dem Wert 4 statt dem Fragenzeigen bekommst Du die Ergebnisse?
- Was passiert wenn Du team.getMembers.add(newMember) und danach session.save(team) machst? (Vorher newMember anlegen und ebenfalls mit save speichern) => Dann müsste in der DB ein zusätzlicher Eintrag angelegt werden...

Probier das mal bitte durch


Top
 Profile  
 
 Post subject:
PostPosted: Tue Jan 27, 2009 5:44 pm 
Newbie

Joined: Fri Jan 23, 2009 2:32 pm
Posts: 7
pkleindl wrote:
Step by step:
- Team ist sicher geladen, dh Du kannst zB Name ausgeben?

Ja, der Name des Teams kommt
Quote:
- Team.getId() retourniert 4?

Ja, getId() gibt 4 aus
Quote:
- Wenn Du das SQL kopierst und direkt ausführst (DB Client) mit dem Wert 4 statt dem Fragenzeigen bekommst Du die Ergebnisse?

Ja, es listet mir die zwei Member auf die zum Team gehoeren (toll, hab nicht gewusst, dass man das so machen kann)
Quote:
- Was passiert wenn Du team.getMembers.add(newMember) und danach session.save(team) machst? (Vorher newMember anlegen und ebenfalls mit save speichern) => Dann müsste in der DB ein zusätzlicher Eintrag angelegt werden...

Ich habe jetzt einen neuen Member instanziert und mit save() gespeichert, dieser erscheint in der DB. Dann den Member mit add() zum Team dazugefuegt, und das Team mit save() gespeichert, doch dies ist in der DB nicht sichtbar (in der Tabelle Team_Members sollte jetzt ein Eintrag sein mit den beiden IDs von Team und Member).
Beim neuen Member anlegen und speichern kommt in der Console auch ein insert, wenn ich aber den Member zum Team hinzufuege und save() aufrufe gibt es mir kein SQL auf der Console aus. Auch sehe ich keine Exception oder so. ratlos.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Jan 27, 2009 6:06 pm 
Newbie

Joined: Fri Jan 23, 2009 2:32 pm
Posts: 7
Quote:
Beim neuen Member anlegen und speichern kommt in der Console auch ein insert, wenn ich aber den Member zum Team hinzufuege und save() aufrufe gibt es mir kein SQL auf der Console aus. Auch sehe ich keine Exception oder so. ratlos.

Wenn ich danach flush() aufrufe, dann werden die zwei Eintraege in Team_Members geloescht, die zum Team gehoeren und der neue Member wird eingetragen.

SQL nach flush():
Code:
delete
    from
        TEAM_MEMBERS
    where
        TEAM_ID=?
Hibernate:
    insert
    into
        TEAM_MEMBERS
        (TEAM_ID, MEMBER_ID)
    values
        (?, ?)


Top
 Profile  
 
 Post subject:
PostPosted: Tue Jan 27, 2009 6:48 pm 
Senior
Senior

Joined: Thu Jan 08, 2009 3:48 pm
Posts: 168
Interessant, das Verhalten mit DELETE/INSERT sollte laut Anleitung nur bei BAG collections auftreten
Quote:
Bags are the worst case. Since a bag permits duplicate element values and has no index column, no primary key may be defined. Hibernate has no way of distinguishing between duplicate rows. Hibernate resolves this problem by completely removing (in a single DELETE) and recreating the collection whenever it changes. This might be very inefficient.


Im ursprünglichen Zustand mit 2 TEAM_MEMBERS, was kommt raus wenn Du team.getMembers().size() abfragst?

Wenn Du direkt nach Deinem letzten Beispiel (DELETE/INSERT) die Members abfragst, was steht dann drin?
Was beim nächsten Programm-Aufruf?

Post bitte auch mal deine Java-Klassen und den Code-Teil wo Du die Aufrufe machst.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Feb 02, 2009 5:37 pm 
Newbie

Joined: Fri Jan 23, 2009 2:32 pm
Posts: 7
Habe den Fehler doch noch gefunden. Team#setMembers() war leer... so kann natuerlich nichts hineinkommen.

Jetzt laeufts wunderbar. Hat mich einiges an Zeit gekostet, aber diesen Fehler mach ich nicht mehr.

Vielen Dank fuer deine Zeit und Hilfe.

gruess stephan


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 10 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.