-->
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.  [ 3 posts ] 
Author Message
 Post subject: OneToOne Lazy via LazyToOneOption.PROXY Does Not Work in 3.5
PostPosted: Tue Apr 20, 2010 3:32 pm 
Beginner
Beginner

Joined: Wed Nov 10, 2004 5:48 pm
Posts: 32
Location: Portland
I'm using 3.5.1. Two persistent entities, parent and child, are in a one to one relationship:

In Parent, the reference to Child:
Code:
   @OneToOne(optional=false, fetch=FetchType.LAZY, cascade={ CascadeType.MERGE, CascadeType.REMOVE, CascadeType.REFRESH, CascadeType.PERSIST })
   @LazyToOne(LazyToOneOption.PROXY)
   @JoinColumn(name = "childId")
   @ForeignKey(name="FK_Parent_Child")
   @IndexedEmbedded()
   public Child getChild() {
      return child;
   }
   public void setChild(Child child) {
      this.child = child;
   }


And in Child, the reference to Parent:
Code:
   @OneToOne(mappedBy="child", fetch=FetchType.LAZY)
   @LazyToOne(LazyToOneOption.PROXY)
   @ContainedIn 
   public Parent getParent() {
      return parent;
   }
   public void setParent(Parent parent) {
      this.parent = parent;
   }


When I load a Parent entity via HQL, I see three SQL queries:
-one that corresponds to my HQL query
-one that loads Child
-one that loads Parent from the Child's perspective

I'm watching it in JProfiler and it's hurting our app performance significantly because Child contains LOBs that are rarely needed.

Anyone got an idea?

Thanks,

Jeff


Top
 Profile  
 
 Post subject: Re: OneToOne Lazy via LazyToOneOption.PROXY Does Not Work in 3.5
PostPosted: Tue Apr 27, 2010 7:56 pm 
Beginner
Beginner

Joined: Wed Nov 10, 2004 5:48 pm
Posts: 32
Location: Portland
I'll answer my own question:

For the example shown above, the 'child' or 'owned' class needs to be annotated with @Proxy(lazy=true) to get lazy loading. Other than that the example is correct.

If the OneToOne is optional there is no way to get lazy loading with Hibernate. It just can't be done, at least from what I've found. The relationship will always be eagerly loaded.

There's a good reason for this - if they proxied the child object and ran the lazy load on any method call everything would be find except if you ever did:
if (child == null)
you would get the wrong answer; it is never null because of the proxy.

This seems like a significant flaw in JPA (not really Hibernate; I assume other JPA implementations have the same problem, though I have to admit I'm not sure of this). It causes approx 10x slowdown in my app because there are lots of optional @ManyToOne and a few optional @OneToOne relationships.


Top
 Profile  
 
 Post subject: Re: OneToOne Lazy via LazyToOneOption.PROXY Does Not Work in 3.5
PostPosted: Fri Nov 19, 2010 12:14 pm 
Newbie

Joined: Fri Nov 19, 2010 11:27 am
Posts: 2
For me there are still two important questions left:
If I select N parent entities...

1) High number of additional queries:
Why does Hibernate select the associated entities via N single additional select queries? The high number of additional query is the real performance problem for me, not the fetching itself. Why can't Hibernate select all N associated entities with a single additional query? (Or why is Hibernate unable to extend the primary query automatically by the join fetches necessary to load the associated entities within the first query?)

2) Lazy fetching using Byte Code Enhancement is not working either:
I'm using entities with property based access and annotations for lazy loading. To allow Hibernate to instrument my getters, I apply the build-time Hibernate byte code enhancement (org.hibernate.tool.instrument.javassist.InstrumentTask) on all of my entity classes. But also the classes get modified by the enhancement step, it does not change Hibernate's behavior on runtime. Hibernate still fetches all associated entities via N single select queries as before. Why does the Hibernate byte code enhancement not allow for lazy fetching of my 1to1 associations? Is this an additional limitation of the JPA interface? Am I using the wrong Hibernate byte code enhancement method? Is lazy loading of 1to1 associations using build-time enhanced entities working at all?


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