Quantcast

Eager fetch (and lazy load) with one-to-many

classic Classic list List threaded Threaded
7 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

Eager fetch (and lazy load) with one-to-many

Shin Tai
Hi,

We've got a problem with eager fetching where there's a one-to-many
relationship and lazy loading. The code below works if we refresh the
results after doing a findbyName but it's not an ideal solution. Any
ideas as to why this is happening? Thanks in advance

class LolCat {
        String id
        String name // unique identifier
        List cats = []
        static mapping = {
                id generator: 'uuid'
                cats lazy: false
        }

    static fetchMode = [cats: 'eager'] // Turn this off and test passes
    static hasMany = [cats: Cat]
}

class Cat {
    String id
    List images = [] // friendlyName:fileName
    static mapping = { id generator: 'uuid' }
}

class LolCatEagerTests extends GroovyTestCase {
    def sessionFactory
    void testThatAssetsAlsoInSoapsModuleLoadCorrectly() {

        Cat cat1 = new Cat(images:['fluffy','stuckInHole.jpg'])
        Cat cat2 = new Cat(images:['fugly','wormhole.jpg'])
        Cat cat3 = new Cat(images:['ninjas','istenninjas.jpg'])
        assert [cat1, cat2, cat3]*.save(flush: true)

        LolCat lolcat = new LolCat(name: 'ourLolCat');
        lolcat.cats = [cat1, cat2, cat3]
        assert lolcat.save(flush: true), lolcat.errors
        sessionFactory.currentSession.clear()

        lolcat = LolCat.findByName('ourLolCat')
//        lolcat.refresh() //This makes the test work
        assertEquals 3, lolcat.cats.size() // <------------ size is 1!!
    }
}

---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email


Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

Re: Eager fetch (and lazy load) with one-to-many

Robert Fletcher
Try putting
   static belongsTo = [LolCat]
on the Cat class.

The relationship between fetchMode eager, lazy false and belongsTo is
quite confusing. With some combinations you'll get a nice join fetch,
with others a n+1 select and with others this problem you're seeing.

---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email


Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

Re: Eager fetch (and lazy load) with one-to-many

Shin Tai
Thanks Rob,

Gave it a go but had no luck

2008/10/30 Robert Fletcher <[hidden email]>:
> Try putting
>   static belongsTo = [LolCat]
> on the Cat class.
>
> The relationship between fetchMode eager, lazy false and belongsTo is
> quite confusing. With some combinations you'll get a nice join fetch,
> with others a n+1 select and with others this problem you're seeing.
>

---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email


Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

Re: Eager fetch (and lazy load) with one-to-many

Richard Hart
In reply to this post by Shin Tai
Along with Robert's solution, what about:

LolCat lolcat = new LolCat(name: 'ourLolCat').save(flush:true)
cats.each{ cat ->
    lolcat.addToCats(cat).save(flush:true)
}

That should get around you having to do a refresh on lolcat.
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

Re: Eager fetch (and lazy load) with one-to-many

Kevin Richards-2
The problem is not when saving the object, but when retrieving it.    The database correctly contains the 3 related objects - it's just the query doesn't return the correct values - that's why a refresh works.

lolcat = LolCat.findByName('ourLolCat')

I've seen another post - which describes a similar problem and they seemed to have traced this to a problem in the findBy code where  the query generated had a limit parameter which was not filled in - however I'm not sure if this was a bug fixed in 1.0.3.  I'll try and trace the post.

Kev






2008/10/31 Richard Hart <[hidden email]>

What about:

LolCat lolcat = new LolCat(name: 'ourLolCat').save(flush:true)
cats.each{ cat ->
   lolcat.addToCats(cat).save(flush:true)
}

That should get around you having to do a refresh on lolcat.
--
View this message in context: http://www.nabble.com/Eager-fetch-%28and-lazy-load%29-with-one-to-many-tp20246587p20262594.html
Sent from the grails - user mailing list archive at Nabble.com.


---------------------------------------------------------------------
To unsubscribe from this list, please visit:

   http://xircles.codehaus.org/manage_email



Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

Re: Eager fetch (and lazy load) with one-to-many

Kevin Richards-2
Here's that post I saw - it seems to refer to Mysql - it may be a coincidence but it sounds very similar to the problem that Shin reported.

http://markmail.org/message/poqcu5wfdhlktfzc

Kevin

2008/10/31 Kevin Richards <[hidden email]>
The problem is not when saving the object, but when retrieving it.    The database correctly contains the 3 related objects - it's just the query doesn't return the correct values - that's why a refresh works.

lolcat = LolCat.findByName('ourLolCat')

I've seen another post - which describes a similar problem and they seemed to have traced this to a problem in the findBy code where  the query generated had a limit parameter which was not filled in - however I'm not sure if this was a bug fixed in 1.0.3.  I'll try and trace the post.

Kev






2008/10/31 Richard Hart <[hidden email]>


What about:

LolCat lolcat = new LolCat(name: 'ourLolCat').save(flush:true)
cats.each{ cat ->
   lolcat.addToCats(cat).save(flush:true)
}

That should get around you having to do a refresh on lolcat.
--
View this message in context: http://www.nabble.com/Eager-fetch-%28and-lazy-load%29-with-one-to-many-tp20246587p20262594.html
Sent from the grails - user mailing list archive at Nabble.com.


---------------------------------------------------------------------
To unsubscribe from this list, please visit:

   http://xircles.codehaus.org/manage_email




Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

Re: Eager fetch (and lazy load) with one-to-many

Richard Hart
In reply to this post by Kevin Richards-2
I had the same problem in the past though, where the objects were being persisted, and were not being shown in the application unless I did a refresh. I found that switching over to the addTo* methods, which seems to be "right" way of storing relationships meant I didn't have to perform the refresh.

Kevin Richards-2 wrote
The problem is not when saving the object, but when retrieving it.    The
database correctly contains the 3 related objects - it's just the query
doesn't return the correct values - that's why a refresh works.
Loading...