-->
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.  [ 2 posts ] 
Author Message
 Post subject: Eager fetch n+1 problem
PostPosted: Fri Apr 02, 2010 5:48 am 
Pro
Pro

Joined: Wed Nov 05, 2003 7:22 pm
Posts: 211
Hi,

I have two classes
Offer and Visibility. There is a 1-1 relation between Offer and visibility
Code:
Offer
        @OneToOne(optional = false, cascade = CascadeType.ALL, fetch = FetchType.EAGER)
   @JoinColumn(name = "FK_VisibilityID",nullable=false,updatable=false)
   @IndexedEmbedded
   public Visibility getVisibility() {
      return visibility;
   }
Visibility
@OneToOne(mappedBy="visibility")
   public Offer getOffer() {
      return offer;
   }


When I make a selection of offers, Hibernate always executes #records queries against the visibility table. Even when I use fetchmode join in the query. This is not great for performance and I just want Hibernate to retrieve the Offer-visibility pair in one go. I think it actually does but then redundantly retrieves the visibility separately

This are examples of a query with the problem:
Code:
   public List<Offer> getOffers(Long[] ids) {
      DetachedCriteria dc = DetachedCriteria.forClass(Offer.class);
      dc.setFetchMode("visibility", FetchMode.JOIN).add(
            Restrictions.in("id", ids));
      return getHibernateTemplate().findByCriteria(dc);
   }

a HQL one

        from Offer o inner join fetch o.visibility


What I will see on these queries is the query being executed and then #records separate queries against the visibility table based on visibilityId. This all happens in the context of the execution of the query

Any ideas?

Kind regards,

Marc


Top
 Profile  
 
 Post subject: Re: Eager fetch n+1 problem
PostPosted: Sun Apr 04, 2010 6:08 pm 
Pro
Pro

Joined: Wed Nov 05, 2003 7:22 pm
Posts: 211
Ok, the reason is
Code:
Visibility
@OneToOne(mappedBy="visibility")
   public Offer getOffer() {
      return offer;
   }


If I map it like so

Code:
Visibility
@Transient
   public Offer getOffer() {
      return offer;
   }


or remove it entirely, I don't have the problem anymore. The underlying reason appears to be that if there is a OneToOne mapping on this, Hibernate needs to know whether it is null or not and executes the extra query. Seems to me that Hibernate should be able to deduce the complete state of Visibility from the eagerly fetched visibility relation from the Offer side, but there you have it.

Kind regards,

Marc


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