You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@cocoon.apache.org by Jorg Heymans <jh...@domek.be> on 2004/09/24 15:25:53 UTC
repeater calls row-path method n+1 times
Hi,
Bringing this over from user@ , this is just too unlogical for me.
Say formbean has a Collection called "smallbeans" of "smallbean" objects
and i want to have a repeater for this.
then the binding looks like
<fb:repeater id="myrepeater" parent-path="." row-path="smallbeans">
formbean.java has getSmallbeans() and setSmallbeans().
When loading this repeater, getSmallbeans() gets called n+1 times, where
n is the number of elements in the collection. Now lets say that the
repeater is populated from a fairly heave database query that returns
around 100 entries - you get the picture :)
Is this a normal repeater feature? Shouldn't it be enough for the
repeater to call the method only once as it returns the whole collection
anyway?
Thoughts?
Jorg Heymans
Re: repeater calls row-path method n+1 times
Posted by Jorg Heymans <jh...@domek.be>.
PS: tested this against in 2.1.5 and 2.1 trunk, same behaviour.
Jorg Heymans wrote:
> Hi,
>
> Bringing this over from user@ , this is just too unlogical for me.
>
> Say formbean has a Collection called "smallbeans" of "smallbean" objects
> and i want to have a repeater for this.
>
> then the binding looks like
> <fb:repeater id="myrepeater" parent-path="." row-path="smallbeans">
>
> formbean.java has getSmallbeans() and setSmallbeans().
>
> When loading this repeater, getSmallbeans() gets called n+1 times, where
> n is the number of elements in the collection. Now lets say that the
> repeater is populated from a fairly heave database query that returns
> around 100 entries - you get the picture :)
>
> Is this a normal repeater feature? Shouldn't it be enough for the
> repeater to call the method only once as it returns the whole collection
> anyway?
>
>
> Thoughts?
> Jorg Heymans
>
>
Re: repeater calls row-path method n+1 times
Posted by Jorg Heymans <jh...@domek.be>.
Vadim Gritsenko wrote:
>
> Not to prevent you from tinkering with this code, but a side comment
> about "hooking up an O/R mapping". I don't think I'd be totally off mark
> if I were to say that any respectable O/R mapping will make sure that:
>
> * Any obj.get() will pull information from database only once during
> the life of the transaction, and only in case lazy loading is used
s/will/should/ , and only when configured to do so. It's hibernate i am
using, for the moment it's setup not to do any caching at all. Note that
at this point in my app i don't need to write anything back, so there
are no transactions involved yet.
> * Any set() won't write anything to database at all till some kind of
> obj.commit() or service.store(obj) is called
true.
>
> Given these two points, it becomes less important how many times set/get
> is called. But it does not mean it should not be fixed :)
Well depends, i don't know (yet) what CForms does 12 times with the
collection it retrieves. If it's a large collection and CForms is doing
something else besides array reference assigning then it will become
problematic in terms of performance.
>
> PS Never worked with OJB / hibernate yet; how do they operate in such
> situation? IIRC, JDO operates exactly as described above.
It works quite well up until know. I have a huge datamodel to deal with,
used middlegen to extract the O/R mapping from the database and generate
the hibernate classes. It saved me heaps of time.
Jorg
Re: repeater calls row-path method n+1 times
Posted by Vadim Gritsenko <va...@reverycodes.com>.
Jorg Heymans wrote:
> I took the form2bean.flow example that is under CForms Block Samples
> (link is called "Bean Binding") and enhanced Form2Bean.java with a bit
> of get/set logging. I changed the calling flowscript method (form2bean
> in binding_example.js) to add 4 Contacts instead of 1.
>
> Findings:
> - getContacts() is called 5 times upon loading
> - when removing 3 elements and saving the form, getContacts() is called
> 7 times. setContacts() is called once for each removed element.
> - at the end getContacts() is called another 3 times.
>
> This is important to know when hooking up CForms to an O/R mapping. I am
> curious to know how other people have gotten around this when dealing
> with large repeaters.
Not to prevent you from tinkering with this code, but a side comment
about "hooking up an O/R mapping". I don't think I'd be totally off mark
if I were to say that any respectable O/R mapping will make sure that:
* Any obj.get() will pull information from database only once during
the life of the transaction, and only in case lazy loading is used
* Any set() won't write anything to database at all till some kind of
obj.commit() or service.store(obj) is called
Given these two points, it becomes less important how many times set/get
is called. But it does not mean it should not be fixed :)
PS Never worked with OJB / hibernate yet; how do they operate in such
situation? IIRC, JDO operates exactly as described above.
Vadim
Re: repeater calls row-path method n+1 times
Posted by Jorg Heymans <jh...@domek.be>.
I took the form2bean.flow example that is under CForms Block Samples
(link is called "Bean Binding") and enhanced Form2Bean.java with a bit
of get/set logging. I changed the calling flowscript method (form2bean
in binding_example.js) to add 4 Contacts instead of 1.
Findings:
- getContacts() is called 5 times upon loading
- when removing 3 elements and saving the form, getContacts() is called
7 times. setContacts() is called once for each removed element.
- at the end getContacts() is called another 3 times.
This is important to know when hooking up CForms to an O/R mapping. I am
curious to know how other people have gotten around this when dealing
with large repeaters.
Here is the output in case anyone is interested.
Upon loading the form initially
---------------------------------
addContact() 1
addContact() 2
addContact() 3
addContact() 4
getContacts() returning collection of size 4
elements are :
id=1 name=Hermann1
id=2 name=Hermann2
id=3 name=Hermann3
id=4 name=Hermann4
end getContacts()
getContacts() returning collection of size 4
elements are :
id=1 name=Hermann1
id=2 name=Hermann2
id=3 name=Hermann3
id=4 name=Hermann4
end getContacts()
getContacts() returning collection of size 4
elements are :
id=1 name=Hermann1
id=2 name=Hermann2
id=3 name=Hermann3
id=4 name=Hermann4
end getContacts()
getContacts() returning collection of size 4
elements are :
id=1 name=Hermann1
id=2 name=Hermann2
id=3 name=Hermann3
id=4 name=Hermann4
end getContacts()
getContacts() returning collection of size 4
elements are :
id=1 name=Hermann1
id=2 name=Hermann2
id=3 name=Hermann3
id=4 name=Hermann4
end getContacts()
removed contact 4,3,2 using the repeater remove button, pressed submit
-----------------------------------------------------------------------
getContacts() returning collection of size 4
elements are :
id=1 name=Hermann1
id=2 name=Hermann2
id=3 name=Hermann3
id=4 name=Hermann4
end getContacts()
getContacts() returning collection of size 4
elements are :
id=1 name=Hermann1
id=2 name=Hermann2
id=3 name=Hermann3
id=4 name=Hermann4
end getContacts()
getContacts() returning collection of size 4
elements are :
id=1 name=Hermann1
id=2 name=Hermann2
id=3 name=Hermann3
id=4 name=Hermann4
end getContacts()
getContacts() returning collection of size 4
elements are :
id=1 name=Hermann1
id=2 name=Hermann2
id=3 name=Hermann3
id=4 name=Hermann4
end getContacts()
getContacts() returning collection of size 4
elements are :
id=1 name=Hermann1
id=2 name=Hermann2
id=3 name=Hermann3
id=4 name=Hermann4
end getContacts()
getContacts() returning collection of size 4
elements are :
id=1 name=Hermann1
id=2 name=Hermann2
id=3 name=Hermann3
id=4 name=Hermann4
end getContacts()
getContacts() returning collection of size 4
elements are :
id=1 name=Hermann1
id=2 name=Hermann2
id=3 name=Hermann3
id=4 name=Hermann4
end getContacts()
setContacts() with collection of size 3
elements are :
id=1 name=Hermann1
id=2 name=Hermann2
id=3 name=Hermann3
end setContacts()
setContacts() with collection of size 2
elements are :
id=1 name=Hermann1
id=2 name=Hermann2
end setContacts()
setContacts() with collection of size 1
elements are :
id=1 name=Hermann1
end setContacts()
getContacts() returning collection of size 1
elements are :
id=1 name=Hermann1
end getContacts()
getContacts() returning collection of size 1
elements are :
id=1 name=Hermann1
end getContacts()
getContacts() returning collection of size 1
elements are :
id=1 name=Hermann1
end getContacts()
Jorg Heymans wrote:
> Hi,
>
> Bringing this over from user@ , this is just too unlogical for me.
>
> Say formbean has a Collection called "smallbeans" of "smallbean" objects
> and i want to have a repeater for this.
>
> then the binding looks like
> <fb:repeater id="myrepeater" parent-path="." row-path="smallbeans">
>
> formbean.java has getSmallbeans() and setSmallbeans().
>
> When loading this repeater, getSmallbeans() gets called n+1 times, where
> n is the number of elements in the collection. Now lets say that the
> repeater is populated from a fairly heave database query that returns
> around 100 entries - you get the picture :)
>
> Is this a normal repeater feature? Shouldn't it be enough for the
> repeater to call the method only once as it returns the whole collection
> anyway?
>
>
> Thoughts?
> Jorg Heymans
>
>