-->
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.  [ 20 posts ]  Go to page 1, 2  Next
Author Message
 Post subject: Problem mit Layz loading bei one-to-many
PostPosted: Thu Feb 26, 2009 10:12 am 
Newbie

Joined: Mon Jul 21, 2008 5:52 am
Posts: 13
Hy Forum,

ich habe da eine kleine Verständnissfrage bzgl. Lazy Loading.

Ich habe 3 Entitäten, Adresse, Unterlagen, UnterlagenGesendet. Adresse ist eine Adresse mit:

--- cut ---
<hibernate-mapping>
<class name="de.einsle.segeln.data.model.Adresse" table="adresse">
<id name="adressId" type="long">
<column name="adress_id" />
<generator class="identity" />
</id>
<property name="kdNr" type="string">
<column name="kd_nr" length="10" />
</property>
[...]
<set name="unterlagenGesendets" inverse="true" lazy="true" cascade="delete">
<key>
<column name="adress_id" not-null="true" />
</key>
<one-to-many class="de.einsle.segeln.data.model.UnterlagenGesendet" />
</set>
</class>
</hibernate-mapping>
--- cut ---

Dazu Unterlagen

--- cut ---
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- Generated 07.02.2009 17:51:23 by Hibernate Tools 3.2.2.GA -->
<hibernate-mapping>
<class name="de.einsle.segeln.data.model.Unterlagen" table="unterlagen">
<id name="unterlagenId" type="long">
<column name="unterlagen_id" />
<generator class="identity" />
</id>
<property name="unterlagen" type="string">
<column name="unterlagen" length="64" />
</property>
[...]
<set name="unterlagenGesendets" inverse="true" lazy="true" cascade="delete">
<key>
<column name="unterlagen_id" not-null="true" />
</key>
<one-to-many class="de.einsle.segeln.data.model.UnterlagenGesendet" />
</set>
</class>
</hibernate-mapping>
--- cut ---

Dazu UnterlagenGesendet

--- cut ---
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- Generated 07.02.2009 17:51:23 by Hibernate Tools 3.2.2.GA -->
<hibernate-mapping>
<class name="de.einsle.segeln.data.model.UnterlagenGesendet" table="unterlagen_gesendet">
<composite-id name="id" class="de.einsle.segeln.data.model.UnterlagenGesendetId">
<key-property name="adressId" type="long">
<column name="adress_id" />
</key-property>
<key-property name="unterlagenId" type="long">
<column name="unterlagen_id" />
</key-property>
</composite-id>
<property name="gesendet" type="date">
<column name="gesendet" length="13" />
</property>
[...]
<many-to-one name="unterlagen" class="de.einsle.segeln.data.model.Unterlagen" update="false" insert="false" fetch="select" >
<column name="unterlagen_id" not-null="true" />
</many-to-one>
<many-to-one name="adresse" class="de.einsle.segeln.data.model.Adresse" update="false" insert="false" fetch="select">
<column name="adress_id" not-null="true" />
</many-to-one>
</class>
</hibernate-mapping>
--- cut ---

Die Pojos dazu sind analog, ich denke nicht das ich die Posten brauch.

Jetzt habe ich das Problem z.B. beim Laden der Adresse, das der automatisch einen Select auf die UnterlagenGesendet mitmacht.

--- cut ---
Hibernate: select adresse0_.adress_id as adress1_0_, adresse0_.parent_adress_id as parent2_0_, adresse0_.kd_nr as kd3_0_, adresse0_.status as status0_, adresse0_.markierung as markierung0_, adresse0_.deaktiv_datum as deaktiv6_0_, adresse0_.loesch_datum as loesch7_0_, adresse0_.eingabe_datum as eingabe8_0_, adresse0_.anfrage_datum as anfrage9_0_, adresse0_.titel as titel0_, adresse0_.name as name0_, adresse0_.vorname as vorname0_, adresse0_.strasse as strasse0_, adresse0_.plz as plz0_, adresse0_.ort as ort0_, adresse0_.land as land0_, adresse0_.geburts_datum as geburts17_0_, adresse0_.geburts_ort as geburts18_0_, adresse0_.tel_priv as tel19_0_, adresse0_.tel_ges as tel20_0_, adresse0_.fax as fax0_, adresse0_.mobil as mobil0_, adresse0_.email as email0_, adresse0_.internet as internet0_, adresse0_.beruf as beruf0_, adresse0_.bemerkung as bemerkung0_, adresse0_.bemerkung_intern as bemerkung27_0_ from adresse adresse0_ order by adresse0_.kd_nr desc
Hibernate: select unterlagen0_.adress_id as adress1_1_, unterlagen0_.unterlagen_id as unterlagen2_1_, unterlagen0_.adress_id as adress1_5_0_, unterlagen0_.unterlagen_id as unterlagen2_5_0_, unterlagen0_.gesendet as gesendet5_0_ from unterlagen_gesendet unterlagen0_ where unterlagen0_.adress_id=?
Hibernate: select unterlagen0_.adress_id as adress1_1_, unterlagen0_.unterlagen_id as unterlagen2_1_, unterlagen0_.adress_id as adress1_5_0_, unterlagen0_.unterlagen_id as unterlagen2_5_0_, unterlagen0_.gesendet as gesendet5_0_ from unterlagen_gesendet unterlagen0_ where unterlagen0_.adress_id=?
Hibernate: select unterlagen0_.adress_id as adress1_1_, unterlagen0_.unterlagen_id as unterlagen2_1_, unterlagen0_.adress_id as adress1_5_0_, unterlagen0_.unterlagen_id as unterlagen2_5_0_, unterlagen0_.gesendet as gesendet5_0_ from unterlagen_gesendet unterlagen0_ where unterlagen0_.adress_id=?
--- cut ---

Versteh ich jetzt irgendwie nicht, weil im Mapping ja steht: lazy="true"

Was ich gerne hätte, das wenn ich die Adresse lade, das nur die Adresse kommt, er also die weiteren Selects nach Unterlagen nicht macht. Brauch ich die Unterlagen, greife ich explizit drauf zu.

Hat hier evtl. jemand eine Idee, was ich hier falsch mache? Ich hab im Moment leider keine Idee mehr.

Hibernate ist 3.3.1, ohne Annotationen, Db ist MySQL 5.1.

Vielen Dank an euch.

Robert


Top
 Profile  
 
 Post subject:
PostPosted: Thu Feb 26, 2009 5:25 pm 
Senior
Senior

Joined: Thu Jan 08, 2009 3:48 pm
Posts: 168
Post mal den Code wo Du die Adressen ladest und was Du danach damit machst.
Schaut auf den ersten Blick so aus als ob Du alle Adressen lädst und dann in einer Schleife darüberiterierst und auf die verbundenen Objekte zugreifst.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Feb 27, 2009 3:03 am 
Newbie

Joined: Mon Jul 21, 2008 5:52 am
Posts: 13
Hy,

also zugegriffen wird hier:

--- cut ---
/**
* Laden der Adressen fuer die Darstellung im Tree
*
* @return die Adressen als Baum
*/
@SuppressWarnings("unchecked")
public Adresse findAdresseTree() {
Adresse root = new Adresse();
List<Adresse> all = getHibernateTemplate().find("from Adresse a");
// List<Adresse> all = getHibernateTemplate().loadAll(Adresse.class);
for (int i = 0; i < all.size(); i++) {
Adresse a = all.get(i);
if (a.getParentAdressId() == null) {
root.getChildren().add(a);
a.setParent(root);
} else {
for (int j = 0; j < all.size(); j++) {
Adresse b = all.get(j);
if (a.getParentAdressId().equals(b.getAdressId())) {
b.getChildren().add(a);
a.setParent(b);
break;
}
}
}
}
return root;
}
--- cut ---

Wobei wie das Beispiel zeigt, hier a) ueber Spring zugegriffen wird, und b) ich immer 2 Wege (HQL, loadAll) probiere. Bei beiden selbiges verhalten. Und das Nachladen geschieht aber auch in der getHibernateTemplate().irgendwas Mthode, nicht danach.

Danke dir

Robert


Top
 Profile  
 
 Post subject:
PostPosted: Fri Feb 27, 2009 12:35 pm 
Senior
Senior

Joined: Thu Jan 08, 2009 3:48 pm
Posts: 168
Hallo

a) Ich trau dem HibernateTemplate von Spring nicht, hat bei uns auch schon für genug Irritationen gesorgt.
Irgendwo hab ich mal einen Artikel gefunden dass man es eigentlich nicht mehr verwenden sollte weil inzwischen Hibernate selbst entsprechende Exceptions werfen kann und zB auch bei den Queries named Parameter unterstützt etc.
Über HibernateTemplate.getSession() solltest Du "normal" mit Hibernate arbeiten können.

b) An welcher Stelle genau was geladen wird kannst Du nur sicher sagen wenn Du debug-meldungen einbaust.
Werden die zusätzlichen selects auch gemacht wenn du die schleife komplett entfernst?

lg

Patrik


Top
 Profile  
 
 Post subject:
PostPosted: Fri Feb 27, 2009 2:17 pm 
Newbie

Joined: Mon Jul 21, 2008 5:52 am
Posts: 13
Oki, dazu gibts ja in Spring doInHibernate. Das kann ich umstellen, das sollte je kein Problem sein.

--- cut ---
List<Adresse> all = getHibernateTemplate().executeFind(new HibernateCallback() {
public Object doInHibernate(Session session) throws HibernateException, SQLException {
Criteria crit = session.createCriteria(Adresse.class);
return crit.list();
}
});
--- cut ---

Gibts ne bessere Möglichkeit?

Zu B) welche Schleife? Das Laden (Log) macht er schon früher, vor der Schleife.

Danke dir mal. Werd da mal weiterprobieren.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Feb 27, 2009 2:28 pm 
Senior
Senior

Joined: Thu Jan 08, 2009 3:48 pm
Posts: 168
Session session = HibernateTemplate.getSession().
session.createQuery(...

Ein unterschied ist schon mal dass das find() von HibernateTemplate eine criteriaQuery macht, zumindest wenn du lazy=false im mapping hättest.

Code:
for (int i = 0; i < all.size(); i++) {
Adresse a = all.get(i);


Das ist eine Schleife ;o)

Entfern mal den ganzen for-Block und schau was dann passiert.

Kanns sein dass du die equals Methode überladen hast (ev. automatisch generiert) und dort auch den Inhalt der Collections vergleichst?

Rating ist willkommen


Top
 Profile  
 
 Post subject:
PostPosted: Fri Feb 27, 2009 2:43 pm 
Newbie

Joined: Mon Jul 21, 2008 5:52 am
Posts: 13
pkleindl wrote:
Session session = HibernateTemplate.getSession().
session.createQuery(...

Ein unterschied ist schon mal dass das find() von HibernateTemplate eine criteriaQuery macht, zumindest wenn du lazy=false im mapping hättest.


Damit bin ich gerade am experimentieren. Danke für den Tipp

Quote:
Code:
for (int i = 0; i < all.size(); i++) {
Adresse a = all.get(i);


Das ist eine Schleife ;o)


Wie gesagt, kann nicht sein, weil ich mit dem Debugger reingehe, und da nen Breakpoint hab, dann lädt er das vor der Schleife.

Quote:
Entfern mal den ganzen for-Block und schau was dann passiert.

Kanns sein dass du die equals Methode überladen hast (ev. automatisch generiert) und dort auch den Inhalt der Collections vergleichst?

Rating ist willkommen


Die equals-Methode guckt so aus:

Code:
   public boolean equals(Object other) {
      if ((this == other))
         return true;
      if ((other == null))
         return false;
      if (!(other instanceof Adresse))
         return false;
      Adresse castOther = (Adresse) other;
      if (getAdressId() == null) {
         return false;
      }
      return (this.getAdressId().equals(castOther.getAdressId()));
   }


Hab mir auch mal hashcode und tostring angeguckt, sind eigentlich auch sauber.

Irgendwie steh ich mit dem Collectionmapping in Hibernate immer auf Krigsfuss *gg*

Danke nochmals

Robert


Top
 Profile  
 
 Post subject:
PostPosted: Fri Feb 27, 2009 3:00 pm 
Newbie

Joined: Mon Jul 21, 2008 5:52 am
Posts: 13
Hy,

also ich hab jetzt mal umgestellt:

Der Zugriff ist jetzt:

Code:
      List<Adresse> all = getHibernateTemplate().executeFind(new HibernateCallback() {
         public Object doInHibernate(Session session) throws HibernateException, SQLException {
            Transaction tx = session.beginTransaction();
            List<Adresse> list = session.createQuery("from Adresse a").list();
            tx.commit();
            return list;
         }
      });


Logging ist auf DEBUG, wenn du magst, guck mal hier: http://pastebin.com/m48378313

Wie gesagt spielt sich alles innerhalb des
Code:
List<Adresse> list = session.createQuery("from Adresse a").list();
ab.

Irgendwas hab ich immer noch falsch.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Feb 27, 2009 3:30 pm 
Senior
Senior

Joined: Thu Jan 08, 2009 3:48 pm
Posts: 168
Ich versteh immer noch nicht warum Du den ganzen Aufruf so verpackst mit dem executeFind etc

Code:
Session session = getHibernateTemplate().getSession();
Transaction tx = session.beginTransaction();
List<Adresse> all = session.createQuery("from Adresse a").list();
tx.commit();


Das Log schaut eh normal aus bis zu
Quote:
2009-02-27 19:52:27,828 DEBUG [main] TwoPhaseLoad M[initializeEntity] - resolving associations for [de.einsle.segeln.data.model.Adresse#1]
2009-02-27 19:52:27,859 DEBUG [main] Loader M[loadCollection] - loading collection: [de.einsle.segeln.data.model.Adresse.unterlagenGesendets#1]


Warum das passiert ist mir etwas rätselhaft.

War jemals lazy=false für die collection?


Top
 Profile  
 
 Post subject:
PostPosted: Fri Feb 27, 2009 3:37 pm 
Newbie

Joined: Mon Jul 21, 2008 5:52 am
Posts: 13
Hy

pkleindl wrote:
Ich versteh immer noch nicht warum Du den ganzen Aufruf so verpackst mit dem executeFind etc

Code:
Session session = getHibernateTemplate().getSession();
Transaction tx = session.beginTransaction();
List<Adresse> all = session.createQuery("from Adresse a").list();
tx.commit();



Weil getSession protected ist, ich also so nicht hinkomme. Aber dazu ist dieses executeIn eigentlich da.

Quote:
Das Log schaut eh normal aus bis zu
Quote:
2009-02-27 19:52:27,828 DEBUG [main] TwoPhaseLoad M[initializeEntity] - resolving associations for [de.einsle.segeln.data.model.Adresse#1]
2009-02-27 19:52:27,859 DEBUG [main] Loader M[loadCollection] - loading collection: [de.einsle.segeln.data.model.Adresse.unterlagenGesendets#1]


Warum das passiert ist mir etwas rätselhaft.

War jemals lazy=false für die collection?


Also das ist mir auch schon aufgefallen, aber ich kann mir keinen Rein drauf machen.

Wie meinst du das mit dem war? Cacht da Hibernate irgendwas? Es war am anfang, als ich das mit den Hibernate-Tools eingelesen habe (DDL to hbm.xml und ddl to .java) defaultmaessig auf lazy=false. Das habe ich aber umgesellt. Was genau ich alles ausprobiert habe, weis ich gar nimmer *gg*

Robert


Top
 Profile  
 
 Post subject:
PostPosted: Fri Feb 27, 2009 8:40 pm 
Senior
Senior

Joined: Thu Jan 08, 2009 3:48 pm
Posts: 168
reinsle wrote:
Wie meinst du das mit dem war? Cacht da Hibernate irgendwas? Es war am anfang, als ich das mit den Hibernate-Tools eingelesen habe (DDL to hbm.xml und ddl to .java) defaultmaessig auf lazy=false. Das habe ich aber umgesellt. Was genau ich alles ausprobiert habe, weis ich gar nimmer *gg*


Damit war gemeint ob es sein könnte dass Du das Mapping nur im Source Folder geändert hast es aber seinen Weg ev. nie ins target Verzeichnis gefunden hat. Ungewöhnlich aber das ist das Problem an sich schon...

Hast Du eigentlich denselben Effekt wenn Du statt Adresse Unterlagen lädst?


Top
 Profile  
 
 Post subject:
PostPosted: Sat Feb 28, 2009 4:55 am 
Newbie

Joined: Mon Jul 21, 2008 5:52 am
Posts: 13
Wenn ich die Unterlagen lade, ist genau selbiges Verhalten. Mein Problem ist halt, ich hab etwas übr 18.000 Adressdatensätze, gut 30 Unterlagen, und jede Menge Verknüpfungen. Ich brauch also Ewig die Daten zu laden.

Also ich hab mehrfah den target-Folder gesäubert (Ist eine Eclipse RCP). Hilft nichts. Ich hab auch im Moment keine Idee mehr.


Top
 Profile  
 
 Post subject:
PostPosted: Sat Feb 28, 2009 6:45 am 
Senior
Senior

Joined: Thu Jan 08, 2009 3:48 pm
Posts: 168
Ein paar Ideen noch:
In Adresse das not-null=true aus dem Mapping entfernen:
Code:
<column name="adress_id" not-null="true" />


In UnterlagenGesendet keine compositeId verwenden

Testweise mal das Retourmapping auf Adresse entfernen.


Top
 Profile  
 
 Post subject:
PostPosted: Sat Feb 28, 2009 9:44 am 
Newbie

Joined: Thu Feb 26, 2009 8:21 pm
Posts: 4
Could you please chat it with english? I really can't understand it.


Top
 Profile  
 
 Post subject:
PostPosted: Sat Feb 28, 2009 10:37 am 
Senior
Senior

Joined: Thu Jan 08, 2009 3:48 pm
Posts: 168
This is the german part of the forum (Deutsch = German).

His problem is about eager loading where its not supposed to happen.

If you have a question i suggest you open a thread in the english-speaking part of the forum.


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 20 posts ]  Go to page 1, 2  Next

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.