Grails
  1. Grails
  2. GRAILS-6551

hasOne results in eager fetching of association

    Details

    • Type: Bug Bug
    • Status: Closed
    • Priority: Major Major
    • Resolution: Won't Fix
    • Affects Version/s: 1.3.3
    • Fix Version/s: None
    • Component/s: None
    • Labels:
      None

      Description

      If I have the following domain model:

      class Author {
          String name
          
          static hasOne = [ location: Location ]
      }
      
      class Location {
          String city
      }
      

      then when I execute this code:

      Author.list().each { a ->
          println a.location.city
      }
      

      I find that the location instances are all loaded up front with separate SELECTs. In other words, they're loaded eagerly. Explicitly specifying the relationship as lazy: true has no effect.

      Perhaps this behaviour is expected, but it seems strange to me.

        Issue Links

          Activity

          Peter Ledbrook created issue -
          Hide
          Peter Ledbrook added a comment -

          Attaching an example project. Run the Grails console and then execute

          new BootStrap().init()
          

          followed by

          Author.list().each { a ->
              println a.name
          }
          

          Even though the above code doesn't use the location at all, you'll see in the console output that the locations for each author are loaded up front.

          Show
          Peter Ledbrook added a comment - Attaching an example project. Run the Grails console and then execute new BootStrap().init() followed by Author.list().each { a -> println a.name } Even though the above code doesn't use the location at all, you'll see in the console output that the locations for each author are loaded up front.
          Peter Ledbrook made changes -
          Field Original Value New Value
          Attachment hasone-example.zip [ 50353 ]
          Graeme Rocher made changes -
          Fix Version/s 1.2.5 [ 16652 ]
          Fix Version/s 1.3.5 [ 16651 ]
          Jeff Scott Brown made changes -
          Fix Version/s 1.3.6 [ 16730 ]
          Fix Version/s 1.3.5 [ 16651 ]
          Jeff Scott Brown made changes -
          Fix Version/s 1.2.5 [ 16652 ]
          Jeff Scott Brown made changes -
          Assignee Jeff Brown [ brownj ]
          Jeff Scott Brown made changes -
          Status Open [ 1 ] In Progress [ 3 ]
          Hide
          Jeff Scott Brown added a comment -

          I have stepped into this a bit and I see that the fetch mode on the corresponding DefaultGrailsDomainClassProperty object is GrailsDomainClassProperty.FETCH_LAZY (0). I am still trying to figure out why the relationship is being eagerly fetched.

          Show
          Jeff Scott Brown added a comment - I have stepped into this a bit and I see that the fetch mode on the corresponding DefaultGrailsDomainClassProperty object is GrailsDomainClassProperty.FETCH_LAZY (0). I am still trying to figure out why the relationship is being eagerly fetched.
          Hide
          Jeff Scott Brown added a comment -

          I have found that even if I use the Hibernate API directly to retrieve an Author, its Location is eagerly fetched. That tells me that the eager fetching is not being triggered by GORM query code.

          Show
          Jeff Scott Brown added a comment - I have found that even if I use the Hibernate API directly to retrieve an Author, its Location is eagerly fetched. That tells me that the eager fetching is not being triggered by GORM query code.
          Hide
          Peter Ledbrook added a comment -

          To add to the confusion, GRAILS-6538 suggests that hasOne results in no extra query.

          Show
          Peter Ledbrook added a comment - To add to the confusion, GRAILS-6538 suggests that hasOne results in no extra query.
          Peter Ledbrook made changes -
          Link This issue is related to GRAILS-6538 [ GRAILS-6538 ]
          Hide
          Peter Ledbrook added a comment -

          OK, ignore that. GRAILS-6538 is talking about an extra query to fetch the Author from the associated location. Different (albeit related) issue.

          Show
          Peter Ledbrook added a comment - OK, ignore that. GRAILS-6538 is talking about an extra query to fetch the Author from the associated location. Different (albeit related) issue.
          Hide
          Peter Ledbrook added a comment -

          http://community.jboss.org/wiki/AShortPrimerOnFetchingStrategies

          (The exception is a one-to-one association with a shared primary key: a proxy for the target of an association can only be used if the target is required. If a Person has a one-to-one association to a Desk entity, the primary key value of the Desk must be the same as the primary key value of the Person. The Desk can only be proxied if the Person primary key column has a foreign key constraint referencing the primary key column of Desk, making it non-optional and required; a Person needs a Desk. If this foreign key constraint is not present, or if the foreign key constraint is not mapped in Hibernate with constrained="true" in XML or optional="false" in annotations, no proxy for a Desk can be used, and Hibernate has to hit the database, either with a join or a secondary immediate query, to find out if the association is really null or not. You can use bytecode injected interception to get lazy loading in that case. Read this page for an alternative explanation of the same issue.)

          So there are some one-to-one mappings in which the association will always be eagerly fetched. Perhaps the issue is that the foreign key constraint is not mapped correctly? Or the 'constrained' is not true?

          Show
          Peter Ledbrook added a comment - http://community.jboss.org/wiki/AShortPrimerOnFetchingStrategies (The exception is a one-to-one association with a shared primary key: a proxy for the target of an association can only be used if the target is required. If a Person has a one-to-one association to a Desk entity, the primary key value of the Desk must be the same as the primary key value of the Person. The Desk can only be proxied if the Person primary key column has a foreign key constraint referencing the primary key column of Desk, making it non-optional and required; a Person needs a Desk. If this foreign key constraint is not present, or if the foreign key constraint is not mapped in Hibernate with constrained="true" in XML or optional="false" in annotations, no proxy for a Desk can be used, and Hibernate has to hit the database, either with a join or a secondary immediate query, to find out if the association is really null or not. You can use bytecode injected interception to get lazy loading in that case. Read this page for an alternative explanation of the same issue.) So there are some one-to-one mappings in which the association will always be eagerly fetched. Perhaps the issue is that the foreign key constraint is not mapped correctly? Or the 'constrained' is not true ?
          Jeff Scott Brown made changes -
          Fix Version/s 1.3.6 [ 16730 ]
          Fix Version/s 1.4-M1 [ 16812 ]
          Hide
          Dana Berke added a comment -

          This appears to be a duplicate of GRAILS-5077.

          Show
          Dana Berke added a comment - This appears to be a duplicate of GRAILS-5077 .
          Jeff Scott Brown made changes -
          Link This issue duplicates GRAILS-5077 [ GRAILS-5077 ]
          Hide
          Jeff Scott Brown added a comment -

          Duplicates GRAILS-5077 which is marked as Won't Fix.

          Show
          Jeff Scott Brown added a comment - Duplicates GRAILS-5077 which is marked as Won't Fix.
          Jeff Scott Brown made changes -
          Fix Version/s 1.4-M1 [ 16812 ]
          Status In Progress [ 3 ] Closed [ 6 ]
          Resolution Won't Fix [ 2 ]
          Contegix Support made changes -
          Project Import Thu Mar 24 21:22:24 CDT 2011 [ 1301019744151 ]
          Burt Beckwith made changes -
          Workflow jira [ 34476 ] Grails [ 46686 ]
          Burt Beckwith made changes -
          Workflow Grails [ 46686 ] Copy of Grails [ 54143 ]
          Burt Beckwith made changes -
          Workflow Copy of Grails [ 54143 ] Grails [ 61553 ]
          Burt Beckwith made changes -
          Workflow Grails [ 61553 ] Grails2 [ 69133 ]
          Burt Beckwith made changes -
          Workflow Grails2 [ 69133 ] jira [ 76778 ]
          Burt Beckwith made changes -
          Workflow jira [ 76778 ] Grails2 [ 85342 ]
          Peter Ledbrook made changes -
          Workflow Grails2 [ 85342 ] jira [ 93746 ]
          Peter Ledbrook made changes -
          Workflow jira [ 93746 ] Grails2 [ 101908 ]

            People

            • Assignee:
              Jeff Scott Brown
              Reporter:
              Peter Ledbrook
            • Votes:
              3 Vote for this issue
              Watchers:
              1 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved:

                Development