-->
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.  [ 7 posts ] 
Author Message
 Post subject: Lazy Loading 1:1 nicht lazy
PostPosted: Wed Apr 01, 2009 11:48 am 
Newbie

Joined: Wed Apr 01, 2009 10:23 am
Posts: 4
Hibernate version: 3.3.1


Hallo Zusammen,

ich habe zwei Objekte mit einer 1 zu 1 Beziehung, die sich beide den Primary Key des ersten Objectes teilen:

ProductMeta --> ProductBasic

Obwohl die Beziehung als "lazy" und "optional=false" definiert ist werden beim Laden (sowohl JPA-QL als auch SQL propiert) der ProductMetas auch die ProductBasics mitgeladen - habe auch nach längerem Googeln keine Idee was hier falsch läuft ...??

Hat jemand 'ne Idee oder zumindest einen guten Workaround (ausser die Beziehung zu Fuß zu verwalten :-) ??

Die Klassen:

Code:
@MappedSuperclass
@Table(name="fri_product_meta")
@SequenceGenerator(
      sequenceName = "seq_product_meta"
     , name = "seq_pm"
     , allocationSize = 1
     , initialValue = 1)
public class ProductMeta{
   protected Long id;
   protected Date version;
   private ProductBasic productBasic;
   
   @Id
   @GeneratedValue(generator="seq_pm", strategy=GenerationType.AUTO)
   @Column(name = "oid", nullable = false, insertable = true, updatable = false)
   public Long getId() {
      return id;
   }

@Version
   @Column(name="optlock")
   public Date getVersion() {
      return version;
   }

@OneToOne(cascade=CascadeType.ALL, optional=false,fetch=FetchType.LAZY)
   @PrimaryKeyJoinColumn
   public ProductBasic getProductBasic() {
      return productBasic;
   }
}

@Entity
@Table(name="fri_product_basic")
public class ProductBasic{

   private Long   id;
   private ProductMeta productMeta;

@Id @GeneratedValue(generator = "oneToOneGenerator")
   @org.hibernate.annotations.GenericGenerator( name = "oneToOneGenerator"
                                             , strategy = "foreign"
                                             , parameters = @Parameter(name="property", value="productMeta"))
   @Column(name="oid_pm")
   public Long getId() {
      return id;
   }

@OneToOne(mappedBy="productBasic", fetch=FetchType.LAZY)
   public ProductMeta getProductMeta() {
      return productMeta;
   }
[/code]


Top
 Profile  
 
 Post subject:
PostPosted: Thu Apr 02, 2009 1:17 pm 
Expert
Expert

Joined: Thu Jan 08, 2009 6:16 am
Posts: 661
Location: Germany
In meinem Fall gehts, hier die Unterschiede:
- Bei mir ists keine MappedSuperclass, sollte daran aber eigentlich nicht
liegen
- die Id wird generiert, aber nicht über eine Sequenz sondern nur mittels @GeneratedValue (in beiden Entities), sollte auch kein Problem sein
- meine beziehung ist nicht bidirektional, vielleicht macht das Probleme?

_________________
-----------------
Need advanced help? http://www.viada.eu


Top
 Profile  
 
 Post subject:
PostPosted: Fri Apr 03, 2009 6:04 am 
Newbie

Joined: Wed Apr 01, 2009 10:23 am
Posts: 4
ja, wenn ich die bidirektionale Beziehung rausnehme, dann funktioniert das lazy loading wieder - danke für den Tipp.

Mmh, so richtig fällt mir kein guter Grund dazu ein ... hier sollte doch beim Laden ein Proxy langen ...?

Wie auch immer, jetzt habe ich das Problem das mein Generated Value so nicht mehr funktioniert:

Code:
@Id @GeneratedValue(generator = "oneToOneGenerator")
   @org.hibernate.annotations.GenericGenerator( name = "oneToOneGenerator"
                                             , strategy = "foreign"
                                             , parameters = @Parameter(name="property", value="productMeta"))


Jetzt werde ich mir also die ID selber aus der Datenbank holen und doch "zu Fuß" in beide Objekte einsetzen - ein anderer Weg fällt mir nicht ein damit beide Objekte die selbe ID bekommen (?).


Top
 Profile  
 
 Post subject:
PostPosted: Fri Apr 03, 2009 8:14 am 
Expert
Expert

Joined: Thu Jan 08, 2009 6:16 am
Posts: 661
Location: Germany
Hmm, im reference manual werden bidirektionale one-to-ones abgebildet, indem eine der beiden Seiten als ManyToOne und Unique gemapppt wird.

Versuch das doch mal bei der bidirektionalen Beziehung (@ManyToOne und @Column(unique=true)).

Zu den Schlüssel-Generatoren: Brauchst du den überhaupt? Wenn du ein ProductBasic speicherst hat es ja immer ein ProductMeta, oder? Sodass dann der Schlüssel des Metas automatisch auch als (Fremd-)Schlüssel für ProductBasic genommen wird.

_________________
-----------------
Need advanced help? http://www.viada.eu


Top
 Profile  
 
 Post subject:
PostPosted: Fri Apr 03, 2009 8:32 am 
Newbie

Joined: Wed Apr 01, 2009 10:23 am
Posts: 4
mmerder wrote:
Zu den Schlüssel-Generatoren: Brauchst du den überhaupt? Wenn du ein ProductBasic speicherst hat es ja immer ein ProductMeta, oder? Sodass dann der Schlüssel des Metas automatisch auch als (Fremd-)Schlüssel für ProductBasic genommen wird.


Das geht denn nun wieder nicht mit der Cascading-Option :-(
Ich erzeuge beide Objekte in der selben Transaktion neu, da Hibernate keine Reihenfolge festlegen kann muss ich den Schlüssel von "aussen" bekommen und setzen, sonst geht das Speichern mit Cascading-Option schief.

Die Alternative ist Hibernate beuizubringen (s.o.) dass es sich um den selben Wert handelt, dafür ist aber die bidirektionale Referenz notwendig - und damit funktioniert das Lazy Loading dann wieder nicht ...

Habe mir jetzt ein drittes Objekt gebaut das ich als KeyFactory benutze, vorher abspeichere und denn die dort erzeugte ID in die beiden anderen Objekte setze.

Bin über das Design nicht wirklich glücklich, aber jetzt funtioniert wieder alles :-)

Trotzdem würde ich natürlich gerne verstehen was da vor sich gegangen ist ?


Top
 Profile  
 
 Post subject:
PostPosted: Fri Apr 03, 2009 8:39 am 
Expert
Expert

Joined: Thu Jan 08, 2009 6:16 am
Posts: 661
Location: Germany
hast du auch mal die manyToOne-Alternative ausprobiert?

_________________
-----------------
Need advanced help? http://www.viada.eu


Top
 Profile  
 
 Post subject:
PostPosted: Fri Apr 03, 2009 9:07 am 
Newbie

Joined: Wed Apr 01, 2009 10:23 am
Posts: 4
mmerder wrote:
hast du auch mal die manyToOne-Alternative ausprobiert?

ja, funktioniert nicht - hierbei generiert hibernate eine fremdschlüssel-spalte in meinem object "produktMeta" - beim insert gibt es hierfür aber noch keinen wert wenn ich wie oben den primary key meines objektes "productBasic" auf den primary key von productMeta verweise; dafür funktioniert das lazyy load aber tatsächlich.

Jetzt könnte ich natürlich einen eigenen key-generator für mein produktBasic einführen - genau das möchte ich aber vermeiden, sondern vielmehr in beiden tabellen (objecten) den selben primary key stehen haben; das erleichterrt erfahrungsgemäß den späteren umgang mit den Daten ungemein (zumahl es hier eigentlich nicht nur um zwei objekte sondern um ein viel komplexeres modell geht).


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