FAQ
Hello,
is lazy loading not supported in cayenne?

best regards
Sheldon

--
View this message in context: http://cayenne.195.n3.nabble.com/lazy-loading-tp3863908p3863908.html
Sent from the Cayenne - User mailing list archive at Nabble.com.

Search Discussions

  • Michael Gentry at Mar 28, 2012 at 12:38 pm
    Hi Sheldon,

    I'm assuming you mean lazy loading of relationships? If so, then yes.
    And it is the default mechanism.

    mrg

    On Wed, Mar 28, 2012 at 4:26 AM, Sheldon wrote:
    Hello,
    is lazy loading not supported in cayenne?

    best regards
    Sheldon

    --
    View this message in context: http://cayenne.195.n3.nabble.com/lazy-loading-tp3863908p3863908.html
    Sent from the Cayenne - User mailing list archive at Nabble.com.
  • Jerome Moliere at Mar 28, 2012 at 12:41 pm
    Hi all...
    Michael I may have not understood the question but from my understanding the answer is NO ....there was a not inside ....
    Jerome
    ------Original Message------
    From: Michael Gentry
    To: user@cayenne.apache.org
    ReplyTo: user@cayenne.apache.org
    Subject: Re: lazy loading
    Sent: Mar 28, 2012 14:37

    Hi Sheldon,

    I'm assuming you mean lazy loading of relationships? If so, then yes.
    And it is the default mechanism.

    mrg

    On Wed, Mar 28, 2012 at 4:26 AM, Sheldon wrote:
    Hello,
    is lazy loading not supported in cayenne?

    best regards
    Sheldon

    --
    View this message in context: http://cayenne.195.n3.nabble.com/lazy-loading-tp3863908p3863908.html
    Sent from the Cayenne - User mailing list archive at Nabble.com.
    ---- Envoyé avec BlackBerry® d'Orange ----
  • Joe Baldwin at Mar 28, 2012 at 1:07 pm
    Unless I am missing something here I believe the problem is rhetorical, i.e. it *appear* like the original question was presented as a "double negative" question which might be confusing things. I think what Michael was saying was, that the answer is that 'lazy loading of data object relationship data is supported and is the default mechanism'. (In fact this is one of the main strengths of Cayenne in my opinion)


    On Mar 28, 2012, at 8:40 AM, jerome.moliere@gmail.com wrote:

    Hi all...
    Michael I may have not understood the question but from my understanding the answer is NO ....there was a not inside ....
    Jerome
    ------Original Message------
    From: Michael Gentry
    To: user@cayenne.apache.org
    ReplyTo: user@cayenne.apache.org
    Subject: Re: lazy loading
    Sent: Mar 28, 2012 14:37

    Hi Sheldon,

    I'm assuming you mean lazy loading of relationships? If so, then yes.
    And it is the default mechanism.

    mrg

    On Wed, Mar 28, 2012 at 4:26 AM, Sheldon wrote:
    Hello,
    is lazy loading not supported in cayenne?

    best regards
    Sheldon

    --
    View this message in context: http://cayenne.195.n3.nabble.com/lazy-loading-tp3863908p3863908.html
    Sent from the Cayenne - User mailing list archive at Nabble.com.
    ---- Envoyé avec BlackBerry® d'Orange ----
  • Durchholz, Joachim at Mar 28, 2012 at 2:05 pm

    I think what Michael was saying was, that the answer is that 'lazy loading
    of data object relationship data is supported and is the default mechanism'.
    That's what I read, too.
    (In fact this is one of the main strengths of Cayenne in my opinion)
    On a tangent, I don't think this can be advertised as a special strength of Cayenne.
    Think about it: Any ORM that does not do by-default lazy association loading will quickly find itself loading the entire database. If it wasn't built into the ORM right from the beginning, the ORM is essentially useless and will either die or get that feature added ASAP.

    The more interesting comparison would be how easily an application developer could specify when to load eagerly.
    (Not that I'm in a position to actually do such a comparison. ;-) )
  • Joe Baldwin at Mar 28, 2012 at 2:20 pm
    on the "aside":

    the last time we discussed this, it appears that Hibernate *implements* the rules differently (and very poorly in my humble opinion), and *so* differently that I would argue that they don't support it vey well. The methodologies behind the Cayenne relationship handling are quite advanced and as "idiot proof" as Java GC.

    On Mar 28, 2012, at 10:04 AM, Durchholz, Joachim wrote:

    I think what Michael was saying was, that the answer is that 'lazy loading
    of data object relationship data is supported and is the default mechanism'.
    That's what I read, too.
    (In fact this is one of the main strengths of Cayenne in my opinion)
    On a tangent, I don't think this can be advertised as a special strength of Cayenne.
    Think about it: Any ORM that does not do by-default lazy association loading will quickly find itself loading the entire database. If it wasn't built into the ORM right from the beginning, the ORM is essentially useless and will either die or get that feature added ASAP.

    The more interesting comparison would be how easily an application developer could specify when to load eagerly.
    (Not that I'm in a position to actually do such a comparison. ;-) )
  • Robert Zeigler at Mar 28, 2012 at 4:00 pm
    Having dealt with this recently in hibernate...

    Hibernate's support for lazy fetching sucks. :) It's there, and it's the default, when possible. But, for instance, toOne relationships can generally only be lazily fetched if they are also mandatory (see, eg: https://community.jboss.org/wiki/SomeExplanationsOnLazyLoadingone-to-one). As a workaround, the hibernate community suggests mapping the toOne as a toMany and creating custom getters/setters (or else build-time instrumentation).

    Every time I'm forced (for client projects) to use hibernate, I find myself wondering how in the /world/ it /ever/ became the dominant player in the ORM world.

    Robert
    On Mar 28, 2012, at 3/289:19 AM , Joe Baldwin wrote:

    on the "aside":

    the last time we discussed this, it appears that Hibernate *implements* the rules differently (and very poorly in my humble opinion), and *so* differently that I would argue that they don't support it vey well. The methodologies behind the Cayenne relationship handling are quite advanced and as "idiot proof" as Java GC.

    On Mar 28, 2012, at 10:04 AM, Durchholz, Joachim wrote:

    I think what Michael was saying was, that the answer is that 'lazy loading
    of data object relationship data is supported and is the default mechanism'.
    That's what I read, too.
    (In fact this is one of the main strengths of Cayenne in my opinion)
    On a tangent, I don't think this can be advertised as a special strength of Cayenne.
    Think about it: Any ORM that does not do by-default lazy association loading will quickly find itself loading the entire database. If it wasn't built into the ORM right from the beginning, the ORM is essentially useless and will either die or get that feature added ASAP.

    The more interesting comparison would be how easily an application developer could specify when to load eagerly.
    (Not that I'm in a position to actually do such a comparison. ;-) )
  • Joe Baldwin at Mar 28, 2012 at 4:51 pm
    Good points and I agree with you.

    As for the "how in the world" comment, I actually know the answer to this (as I had to research this). Technical people will often to "proof of concept" testing (to verify that what the lib developers claim, is actually true). However, management-oriented (i.e. less technically adept) do not have the time, funding, or perhaps skill sets to understand the results of "proof of concept" tests, much less actually doing the tests themselves.

    Sooooo, what they resort to is "follow the leader" - i.e. what did my competitor use in his project - must be good - so I will use it. End of story, go home, have a beer.

    This is analagous to technical people saying: 'what accounting package do you use' - must be good - I will do the same thing.

    This is why I am hoping that Cayenne can get more high-profile projects so that the "follow the leader" pattern will assist in their dissemination.

    On Mar 28, 2012, at 11:59 AM, Robert Zeigler wrote:

    Having dealt with this recently in hibernate...

    Hibernate's support for lazy fetching sucks. :) It's there, and it's the default, when possible. But, for instance, toOne relationships can generally only be lazily fetched if they are also mandatory (see, eg: https://community.jboss.org/wiki/SomeExplanationsOnLazyLoadingone-to-one). As a workaround, the hibernate community suggests mapping the toOne as a toMany and creating custom getters/setters (or else build-time instrumentation).

    Every time I'm forced (for client projects) to use hibernate, I find myself wondering how in the /world/ it /ever/ became the dominant player in the ORM world.

    Robert
    On Mar 28, 2012, at 3/289:19 AM , Joe Baldwin wrote:

    on the "aside":

    the last time we discussed this, it appears that Hibernate *implements* the rules differently (and very poorly in my humble opinion), and *so* differently that I would argue that they don't support it vey well. The methodologies behind the Cayenne relationship handling are quite advanced and as "idiot proof" as Java GC.

    On Mar 28, 2012, at 10:04 AM, Durchholz, Joachim wrote:

    I think what Michael was saying was, that the answer is that 'lazy loading
    of data object relationship data is supported and is the default mechanism'.
    That's what I read, too.
    (In fact this is one of the main strengths of Cayenne in my opinion)
    On a tangent, I don't think this can be advertised as a special strength of Cayenne.
    Think about it: Any ORM that does not do by-default lazy association loading will quickly find itself loading the entire database. If it wasn't built into the ORM right from the beginning, the ORM is essentially useless and will either die or get that feature added ASAP.

    The more interesting comparison would be how easily an application developer could specify when to load eagerly.
    (Not that I'm in a position to actually do such a comparison. ;-) )
  • Durchholz, Joachim at Mar 29, 2012 at 9:34 am

    Every time I'm forced (for client projects) to use hibernate,
    I find myself wondering how in the /world/ it /ever/ became
    the dominant player in the ORM world.
    Hehe, me too.
    Jokes aside, Joe Baldwin has a point. I had to follow the leader myself, since I wasn't allocated the time to do proper research on ORMs, and even if I had, I hadn't known enough about ORMs to investigate in the right directions.

    Anyway. The statement that "having lazy fetching is a specific advantage of Cayenne" is still wrong, most if not all ORMs have that.
    You guys arguing that Cayenne does it better than Hibernate just proves the point that Hibernate does, in fact, have lazy loading of relationships :-)

    (Not that I'd disagree that not having Sessions is a Good Thing. Detached Sessions suck, greatly.)
  • John Huss at Mar 29, 2012 at 2:07 pm
    Someone should write up a document describing the advantages (and
    disadvantages) of Cayenne compared to Hibernate. That would be incredibly
    useful for drawing away some people from the huge community Hibernate has.

    John
    On Thu, Mar 29, 2012 at 4:33 AM, Durchholz, Joachim wrote:

    Every time I'm forced (for client projects) to use hibernate,
    I find myself wondering how in the /world/ it /ever/ became
    the dominant player in the ORM world.
    Hehe, me too.
    Jokes aside, Joe Baldwin has a point. I had to follow the leader myself,
    since I wasn't allocated the time to do proper research on ORMs, and even
    if I had, I hadn't known enough about ORMs to investigate in the right
    directions.

    Anyway. The statement that "having lazy fetching is a specific advantage
    of Cayenne" is still wrong, most if not all ORMs have that.
    You guys arguing that Cayenne does it better than Hibernate just proves
    the point that Hibernate does, in fact, have lazy loading of relationships
    :-)

    (Not that I'd disagree that not having Sessions is a Good Thing. Detached
    Sessions suck, greatly.)
  • Joe Baldwin at Mar 29, 2012 at 2:35 pm
    John,

    there was an excellent thread about this in 2010 (which I sequestered for the very reason you point out). I am going to attach one of Michael Gentry's comments. But I also wanted to say, based on my understanding, in this case the "jokes" are not superfluous, but are at the heart of the matter. I agree with you totally that this issues and others should be a part of a white paper for project managers. However, my point in *this* thread, is that even then, a PM is going to have problems understanding the significance of unpredictable faulting behavior due to a fundamental lack of the cogent behavior mechanisms present in Cayenne ..... - SNORE - ZZZZZZZ - Oh, did you say something, I just dozed off - let's just use Hibernate and make it easy, er, for me. :)

    I did research into this very issue and found, that this issue specifically is a fundamental philosophical difference between the way these two design teams are proceeding to solve ORM issues. Said differently, this is *not* a rhetorical debate, but one based on fundamental design patterns and whether they solve problems better. It appears that Hibernate is not suffering from 'just doing it poorly', and in this the it is clear that the "Gavin Lazy-Fetch" philosophy is not a "mistake" or "oversight", it is an intentional decision to do it differently (and some - including me - might say: not do it at all)

    http://bwinterberg.blogspot.com/2009/08/how-to-eagerly-fetch-associations-with.html


    From Michael 9/6/2010:
    The Hibernate Session is tied to a database connection. A Cayenne DataContext requests a connection from the DB connection pool when you commitChanges() or performQuery() and then releases it when done. Hibernate therefore has issues in a web application where you don't know how many request/response trips will be made from the browser to the application -- you can't really leave the database connection open indefinitely. Cayenne's DataContext transparently uses DB connections
    as needed and is more natural in this regard. Hibernate's proxied objects are also tied to their Session. This creates problems
    (faulting objects, updating and saving, etc) when the Session from one request/response was closed and then you try to use the objects in another request/response -- you have to re-attach objects to a Session. Cumbersome. Again, Cayenne does not have these problems. This issue was so bad in Hibernate that the Spring community created the Open Session In View filter and it still doesn't really solve the problems, but it does make it a little better.
    mrg

    On Mar 29, 2012, at 10:06 AM, John Huss wrote:

    Someone should write up a document describing the advantages (and
    disadvantages) of Cayenne compared to Hibernate. That would be incredibly
    useful for drawing away some people from the huge community Hibernate has.

    John

    On Thu, Mar 29, 2012 at 4:33 AM, Durchholz, Joachim <
    Joachim.Durchholz@hennig-fahrzeugteile.de> wrote:
    Every time I'm forced (for client projects) to use hibernate,
    I find myself wondering how in the /world/ it /ever/ became
    the dominant player in the ORM world.
    Hehe, me too.
    Jokes aside, Joe Baldwin has a point. I had to follow the leader myself,
    since I wasn't allocated the time to do proper research on ORMs, and even
    if I had, I hadn't known enough about ORMs to investigate in the right
    directions.

    Anyway. The statement that "having lazy fetching is a specific advantage
    of Cayenne" is still wrong, most if not all ORMs have that.
    You guys arguing that Cayenne does it better than Hibernate just proves
    the point that Hibernate does, in fact, have lazy loading of relationships
    :-)

    (Not that I'd disagree that not having Sessions is a Good Thing. Detached
    Sessions suck, greatly.)
  • Ashley Aitken at Mar 29, 2012 at 3:24 pm

    Just jumping in here but this may also be interesting to consider given the discussion so far:

    Why can't Hibernate just load objects on demand?
    Every month someone has the idea that Hibernate could instead of throwing a LazyInitializationException just open up a new connection to the database (effectively starting a new Session) and load the collection or initialize the proxy that has been touched on-demand. Of course, this idea, while brilliant at first, has several shortcomings that only appear if you start to think about the consequences of ad-hoc transactional access.

    If Hibernate would, hidden from the developer and outside of any transaction demarcation, start random database connections and transactions, why have transaction demarcation at all? What happens when Hibernate opens a new database connection to load a collection, but the owning entity has been deleted meanwhile? (Note that this problem does not appear with the two-transaction strategy as described above - the single Session provides repeatable reads for entities.) Why even have a service layer when every object can be retrieved by simply navigating to it? How much memory should be consumed by this and which objects should be evicted first? All of this leads to no solution, because Hibernate is a service for online transaction processing (and certain kinds of batch operations) and not a "streaming objects from some persistent data store in undefined units of work"-service. Also, in addition to the n+1 selects problem, do we really need an n+1 transaction and connection problem?

    The solution for this issue is of course proper unit of work demarcation and design, supported by possibly an interception technique as shown in the pattern here, and/or the correct fetch technique so that all required information for a particular unit of work can be retrieved with minimum impact, best performance, and scalability
    from https://community.jboss.org/wiki/OpenSessionInView

    Cheers,
    Ashley.


    --
    Ashley Aitken
    Perth, Western Australia (GMT + 8hrs!)
    Social (Facebook, Twitter, Skype etc.): MrHatken
    Professional (LinkedIn, Twitter, Skype etc.): AshleyAitken
  • Joe Baldwin at Mar 29, 2012 at 5:43 pm
    Remember the "buy a Mac" commercials? When (in the commercial) the Keynote Speaker's presentation was critically interrupted by a Windoz crash, and failure to continue and causing a delay in the presentation, people in the audience were suggesting all sorts of trial solutions one after another (try the registry, try rebooting, ...), so one guy yelled out "Buy a Mac".

    Funny ... but as a Project Management pattern, this "humor" could be applied to solving Hibernate issues (that may be do as much to philosophical belief system as technical inadequacies).

    The new satirical non sequitur, in the context of "fixing Hibernate issues", might be "Download Cayenne". :)

    On Mar 29, 2012, at 11:24 AM, Ashley Aitken wrote:


    Just jumping in here but this may also be interesting to consider given the discussion so far:
    Why can't Hibernate just load objects on demand?
    Every month someone has the idea that Hibernate could instead of throwing a LazyInitializationException just open up a new connection to the database (effectively starting a new Session) and load the collection or initialize the proxy that has been touched on-demand. Of course, this idea, while brilliant at first, has several shortcomings that only appear if you start to think about the consequences of ad-hoc transactional access.

    If Hibernate would, hidden from the developer and outside of any transaction demarcation, start random database connections and transactions, why have transaction demarcation at all? What happens when Hibernate opens a new database connection to load a collection, but the owning entity has been deleted meanwhile? (Note that this problem does not appear with the two-transaction strategy as described above - the single Session provides repeatable reads for entities.) Why even have a service layer when every object can be retrieved by simply navigating to it? How much memory should be consumed by this and which objects should be evicted first? All of this leads to no solution, because Hibernate is a service for online transaction processing (and certain kinds of batch operations) and not a "streaming objects from some persistent data store in undefined units of work"-service. Also, in addition to the n+1 selects problem, do we really need an n+1 transaction and connection problem?

    The solution for this issue is of course proper unit of work demarcation and design, supported by possibly an interception technique as shown in the pattern here, and/or the correct fetch technique so that all required information for a particular unit of work can be retrieved with minimum impact, best performance, and scalability
    from https://community.jboss.org/wiki/OpenSessionInView

    Cheers,
    Ashley.


    --
    Ashley Aitken
    Perth, Western Australia (GMT + 8hrs!)
    Social (Facebook, Twitter, Skype etc.): MrHatken
    Professional (LinkedIn, Twitter, Skype etc.): AshleyAitken
  • Joe Baldwin at Mar 30, 2012 at 12:29 am
    I am interested in the best practice wrt ordering in a certain context.

    Lets say the context is a store with 1000 - 50000 items. I understand that if I can either include the "order by" directive pre-query or post query. Also, I understand that if I have a opportunity, then passing the "order by" to the DBMS is Cayenne-preferred (because, as I understand it) Cayenne can retrieve the result set ordered, and minimize the triggering of faults resulting in minimum memory usage. I think I understand this scenario, and have tried to code to this strategy.

    The second scenario is a tad more complex and really the subject of my concern. Note, if the result set is small, I believe that this is of no concern. However, web-users do not often care about setting off "totally insane queries". So if a query is initiated with 'give me everything you have', then once they see the result set (which I am trying to manage with setPageSize()), they might *then* want to sort the result set (i.e. triggering a "orderList()" which is an in-memory ordering which is not as efficient).

    So given the post-query sorting requirement, a large result set, using setPageSize(), and possibly multiple different post-sorts being initiated, what is the best-practice? Should I resubmit these queries with the ordering, or simply use the orderList() method on the result set? Or, is there another strategy for optimizing coding for these requirements?

    (My intuition, base on reading about Cayenne is that I just need to rely on orderList() and buy more server memory. - but I am not sure)

    Thanks Joe
  • Michael Gentry at Mar 30, 2012 at 12:34 pm
    Hi Joe,

    I think you are on the right path using setPageSize() to limit the
    result set, but even 50k results is a lot of PKs to return (although
    not a ludicrous amount, depending on your users).

    The first approach I would take is if they do a post-query sort then
    send another query to the database with the new sort ordering in place
    and let the database do it.

    Let's say you have 50,000 results and a page size of 20. 50,000 / 20
    = 2500 pages. For you to to sort in-memory using that paginated list
    would require 2499 trips to the database to fetch the records and make
    Java objects out of them (I'm assuming you showed them the first page
    already and they sorted then, so the first page is "free"). 2499
    queries will be a killer latency-wise, even if each query is quick. I
    think it'll be significantly faster to let the database do it,
    especially if you have good indexes in place.

    mrg

    On Thu, Mar 29, 2012 at 8:29 PM, Joe Baldwin wrote:
    I am interested in the best practice wrt ordering in a certain context.

    Lets say the context is a store with 1000 - 50000 items. I understand that if I can either include the "order by" directive pre-query or post query.  Also, I understand that if I have a opportunity, then passing the "order by" to the DBMS is Cayenne-preferred (because, as I understand it) Cayenne can retrieve the result set ordered, and minimize the triggering of faults resulting in minimum memory usage.  I think I understand this scenario, and have tried to code to this strategy.

    The second scenario is a tad more complex and really the subject of my concern.  Note, if the result set is small, I believe that this is of no concern.  However, web-users do not often care about setting off "totally insane queries".  So if a query is initiated with 'give me everything you have', then once they see the result set (which I am trying to manage with setPageSize()), they might *then* want to sort the result set (i.e. triggering a "orderList()" which is an in-memory ordering which is not as efficient).

    So given the post-query sorting requirement, a large result set, using setPageSize(), and possibly multiple different post-sorts being initiated, what is the best-practice?  Should I resubmit these queries with the ordering, or simply use the orderList() method on the result set?  Or, is there another strategy for optimizing coding for these requirements?

    (My intuition, base on reading about Cayenne is that I just need to rely on orderList() and buy more server memory. - but I am not sure)

    Thanks Joe
  • Joe Baldwin at Mar 30, 2012 at 12:57 pm
    OK, good analysis, that makes a lot of sense. So the thing to remember with post-query ordering on large result sets: it is more efficient to re-submit the query to the database.

    At which point (presumably list size) do you think that orderList() becomes reasonable to use on a result set?

    Thanks,
    Joe

    On Mar 30, 2012, at 8:33 AM, Michael Gentry wrote:

    Hi Joe,

    I think you are on the right path using setPageSize() to limit the
    result set, but even 50k results is a lot of PKs to return (although
    not a ludicrous amount, depending on your users).

    The first approach I would take is if they do a post-query sort then
    send another query to the database with the new sort ordering in place
    and let the database do it.

    Let's say you have 50,000 results and a page size of 20. 50,000 / 20
    = 2500 pages. For you to to sort in-memory using that paginated list
    would require 2499 trips to the database to fetch the records and make
    Java objects out of them (I'm assuming you showed them the first page
    already and they sorted then, so the first page is "free"). 2499
    queries will be a killer latency-wise, even if each query is quick. I
    think it'll be significantly faster to let the database do it,
    especially if you have good indexes in place.

    mrg

    On Thu, Mar 29, 2012 at 8:29 PM, Joe Baldwin wrote:
    I am interested in the best practice wrt ordering in a certain context.

    Lets say the context is a store with 1000 - 50000 items. I understand that if I can either include the "order by" directive pre-query or post query. Also, I understand that if I have a opportunity, then passing the "order by" to the DBMS is Cayenne-preferred (because, as I understand it) Cayenne can retrieve the result set ordered, and minimize the triggering of faults resulting in minimum memory usage. I think I understand this scenario, and have tried to code to this strategy.

    The second scenario is a tad more complex and really the subject of my concern. Note, if the result set is small, I believe that this is of no concern. However, web-users do not often care about setting off "totally insane queries". So if a query is initiated with 'give me everything you have', then once they see the result set (which I am trying to manage with setPageSize()), they might *then* want to sort the result set (i.e. triggering a "orderList()" which is an in-memory ordering which is not as efficient).

    So given the post-query sorting requirement, a large result set, using setPageSize(), and possibly multiple different post-sorts being initiated, what is the best-practice? Should I resubmit these queries with the ordering, or simply use the orderList() method on the result set? Or, is there another strategy for optimizing coding for these requirements?

    (My intuition, base on reading about Cayenne is that I just need to rely on orderList() and buy more server memory. - but I am not sure)

    Thanks Joe
  • Sheldon at Mar 30, 2012 at 1:24 pm
    What I mean is,

    if I have a Table with n columns (col1, col2, col3 ...) and want load only
    the value ov col1 and col3 (without loading col2 and the others).
    Is this example possible?

    Sheldon

    --
    View this message in context: http://cayenne.195.n3.nabble.com/lazy-loading-tp3863908p3870794.html
    Sent from the Cayenne - User mailing list archive at Nabble.com.
  • Michael Gentry at Mar 30, 2012 at 1:40 pm
    Hi Joe,

    I've never benchmarked/explored it, but my hunch is the number of
    pages would have to be pretty low (say, less than 3-5). Of course, if
    you are trying to figure out in-memory vs hit the database again, that
    logic just adds a bit more complexity to your code and is more to
    maintain. I think I'd try always hitting the database and see how
    that plays out instead of trying to pre-optimize it.

    mrg

    On Fri, Mar 30, 2012 at 8:57 AM, Joe Baldwin wrote:
    OK, good analysis, that makes a lot of sense. So the thing to remember with post-query ordering on large result sets: it is more efficient to re-submit the query to the database.

    At which point (presumably list size) do you think that orderList() becomes reasonable to use on a result set?

    Thanks,
    Joe

    On Mar 30, 2012, at 8:33 AM, Michael Gentry wrote:

    Hi Joe,

    I think you are on the right path using setPageSize() to limit the
    result set, but even 50k results is a lot of PKs to return (although
    not a ludicrous amount, depending on your users).

    The first approach I would take is if they do a post-query sort then
    send another query to the database with the new sort ordering in place
    and let the database do it.

    Let's say you have 50,000 results and a page size of 20.  50,000 / 20
    = 2500 pages.  For you to to sort in-memory using that paginated list
    would require 2499 trips to the database to fetch the records and make
    Java objects out of them (I'm assuming you showed them the first page
    already and they sorted then, so the first page is "free").  2499
    queries will be a killer latency-wise, even if each query is quick.  I
    think it'll be significantly faster to let the database do it,
    especially if you have good indexes in place.

    mrg

    On Thu, Mar 29, 2012 at 8:29 PM, Joe Baldwin wrote:
    I am interested in the best practice wrt ordering in a certain context.

    Lets say the context is a store with 1000 - 50000 items. I understand that if I can either include the "order by" directive pre-query or post query.  Also, I understand that if I have a opportunity, then passing the "order by" to the DBMS is Cayenne-preferred (because, as I understand it) Cayenne can retrieve the result set ordered, and minimize the triggering of faults resulting in minimum memory usage.  I think I understand this scenario, and have tried to code to this strategy.

    The second scenario is a tad more complex and really the subject of my concern.  Note, if the result set is small, I believe that this is of no concern.  However, web-users do not often care about setting off "totally insane queries".  So if a query is initiated with 'give me everything you have', then once they see the result set (which I am trying to manage with setPageSize()), they might *then* want to sort the result set (i.e. triggering a "orderList()" which is an in-memory ordering which is not as efficient).

    So given the post-query sorting requirement, a large result set, using setPageSize(), and possibly multiple different post-sorts being initiated, what is the best-practice?  Should I resubmit these queries with the ordering, or simply use the orderList() method on the result set?  Or, is there another strategy for optimizing coding for these requirements?

    (My intuition, base on reading about Cayenne is that I just need to rely on orderList() and buy more server memory. - but I am not sure)

    Thanks Joe
  • Joe Baldwin at Mar 29, 2012 at 5:27 pm
    Just re-read my post, and wanted to clear up ambiguous grammar (i.e. poor word use-ments :) )
    lack of the cogent behavior mechanisms present in Cayenne
    This should have said: "lack of cogent behavior mechanisms (that are already present in Cayenne)"

    I totally have to learn English (my native language). :)

    Joe
  • Durchholz, Joachim at Mar 30, 2012 at 12:57 pm
    I agree the difference is the approach.

    Hibernate strictly controls the staleness of objects. If a Session closes, the objects become detached and potentially stale, and there's no way to make the current again (except by transferring their contents to objects of a new Session). Hibernate goes to great lengths to protect that property.
    The downside is that Hibernate cannot deliver on its promise of "work with entities as if they were normal Pojos" - you need to safeguard against LazyInitializationExceptions, either by making sure that everything ever needed is loaded up front (making it really hard to modularize the code), or by restructuring the code so that any update process is wrapped in application-side restartable Action objects, which is a heavy constraint on Java applications (unless they are running inside a web service, where every request is, by nature, already an application-side restartable Action object).

    Cayenne doesn't care about staleness. It's the application's task to ensure that Pojo networks are updated to the current DB state at the beginning of an application-side transaction. If data isn't available yet, just load it - and accept the risk that the application may now be working with partly stale, partly current data.

    If you don't need non-staleness guarantees, Cayenne's way is far easier to work with.
    If you do need non-staleness guarantees, this has massive consequences for application design (i.e. things are getting ugly). Hibernate, IMHO, just exposes this ugliness and enforces it on the application.

    Now that's the conceptual difference. Hibernate also drops the ball on mitigation: you essentially can't recover from a LazyInitializationException (or any other exception), the only thing guaranteed to work is to delete all data and restart the DB transaction. (Again, this is a question of how deeply entrenched your application is in strict transaction control; interactively editing data in the DB definitely does not need that. The irony is that non-interactive code usually does bulk updates, for which an ORM is usually not a good match anyway. I find Hibernate's philosophy valid but suspect that it is suitable only for a rather small ecological niche. It just happens to work reasonably well for web services, which is probably why it gained so much traction.)
  • Andrus Adamchik at Mar 30, 2012 at 1:27 pm
    Hibernate strictly controls the staleness of objects. If a Session closes, the objects become detached and potentially stale, and there's no way to make the current again (except by transferring their contents to objects of a new Session). Hibernate goes to great lengths to protect that property.
    I never used Hibernate, so this may be a dumb question, but how do they reconcile this property with using a variety of object caches in the framework?

    Andrus

    On Mar 30, 2012, at 3:56 PM, Durchholz, Joachim wrote:
    I agree the difference is the approach.

    Hibernate strictly controls the staleness of objects. If a Session closes, the objects become detached and potentially stale, and there's no way to make the current again (except by transferring their contents to objects of a new Session). Hibernate goes to great lengths to protect that property.
    The downside is that Hibernate cannot deliver on its promise of "work with entities as if they were normal Pojos" - you need to safeguard against LazyInitializationExceptions, either by making sure that everything ever needed is loaded up front (making it really hard to modularize the code), or by restructuring the code so that any update process is wrapped in application-side restartable Action objects, which is a heavy constraint on Java applications (unless they are running inside a web service, where every request is, by nature, already an application-side restartable Action object).

    Cayenne doesn't care about staleness. It's the application's task to ensure that Pojo networks are updated to the current DB state at the beginning of an application-side transaction. If data isn't available yet, just load it - and accept the risk that the application may now be working with partly stale, partly current data.

    If you don't need non-staleness guarantees, Cayenne's way is far easier to work with.
    If you do need non-staleness guarantees, this has massive consequences for application design (i.e. things are getting ugly). Hibernate, IMHO, just exposes this ugliness and enforces it on the application.

    Now that's the conceptual difference. Hibernate also drops the ball on mitigation: you essentially can't recover from a LazyInitializationException (or any other exception), the only thing guaranteed to work is to delete all data and restart the DB transaction. (Again, this is a question of how deeply entrenched your application is in strict transaction control; interactively editing data in the DB definitely does not need that. The irony is that non-interactive code usually does bulk updates, for which an ORM is usually not a good match anyway. I find Hibernate's philosophy valid but suspect that it is suitable only for a rather small ecological niche. It just happens to work reasonably well for web services, which is probably why it gained so much traction.)
  • Durchholz, Joachim at Mar 30, 2012 at 1:45 pm

    Hibernate strictly controls the staleness of objects. If a Session
    closes, the objects become detached and potentially stale, and
    there's no way to make the current again (except by transferring
    their contents to objects of a new Session). Hibernate goes to
    great lengths to protect that property.
    I never used Hibernate, so this may be a dumb question, but how do
    they reconcile this property with using a variety of object caches
    in the framework?
    Hibernate has one entity cache per session.
    Its primary purpose is to have the original field values handy for UPDATE statements, that's how they do optimistic locking:
    UPDATE t SET f1 = :newvalue1, f2 = :newvalue2, ...
    WHERE f1 = :oldvalue1 AND f2 = :oldvalue2 AND ...
    The statement returns the number of records changed, so if they get back a zero, they know they have an optimistic locking conflict (and throw an exception, irrecoverably invalidating the Session, grrr).

    This cache does not survive the Session.

    Hibernate itself does not have any more caches. That's why the Hibernate people recommend using a DB cache underneath.
  • Andrus Adamchik at Mar 30, 2012 at 1:48 pm
    Thanks for explaining. If this is so, it this sounds... unscalable.

    On Mar 30, 2012, at 4:45 PM, Durchholz, Joachim wrote:

    Hibernate strictly controls the staleness of objects. If a Session
    closes, the objects become detached and potentially stale, and
    there's no way to make the current again (except by transferring
    their contents to objects of a new Session). Hibernate goes to
    great lengths to protect that property.
    I never used Hibernate, so this may be a dumb question, but how do
    they reconcile this property with using a variety of object caches
    in the framework?
    Hibernate has one entity cache per session.
    Its primary purpose is to have the original field values handy for UPDATE statements, that's how they do optimistic locking:
    UPDATE t SET f1 = :newvalue1, f2 = :newvalue2, ...
    WHERE f1 = :oldvalue1 AND f2 = :oldvalue2 AND ...
    The statement returns the number of records changed, so if they get back a zero, they know they have an optimistic locking conflict (and throw an exception, irrecoverably invalidating the Session, grrr).

    This cache does not survive the Session.

    Hibernate itself does not have any more caches. That's why the Hibernate people recommend using a DB cache underneath.
  • Durchholz, Joachim at Mar 30, 2012 at 2:02 pm
    Thanks for explaining. If this is so, it this sounds... unscalable.
    How so? At worst, the memory footprint doubles (plus maybe a logN factor), that sounds pretty scalable to me. ("non-scalable" is "more than NlogN overhead" in my book; I do not know of any substantially better way to implement optimistic locking unless you assume a VERSION field in each table.)

    Note that Hibernate seems to be slowing to a crawl at a few 10,000 entities in a session cache.
    I have been assuming it's a misimplementation, not a problem in the approach, but that's an unverified assumption so I may be wrong and it's still a problem with the approach in general, so I'd be highly interested in insights here.
  • Andrus Adamchik at Mar 30, 2012 at 2:13 pm

    On Mar 30, 2012, at 5:01 PM, Durchholz, Joachim wrote:

    Thanks for explaining. If this is so, it sounds... unscalable.
    How so?
    You have to inflate your cache anew from DB in every transaction. You don't have any data when you start.

    However I don't think you are right in your assessment. Googling "Hibernate second level cache" shows that its scope goes beyond a single session. And hence my original question - how do they reconcile second level cache presence and the promise of 100% data consistency. My answer is that they don't. So their bigger argument about data consistency is moot.

    Andrus
  • Joe Baldwin at Mar 30, 2012 at 2:35 pm
    Andrus,

    I am pretty smart, but I have NO idea what you just said, :) I would really like to understand your argument as it sounds like something that might be important to my project. Do you have an analysis somewhere I read up on this?

    Thanks
    Joe

    On Mar 30, 2012, at 10:12 AM, Andrus Adamchik wrote:

    On Mar 30, 2012, at 5:01 PM, Durchholz, Joachim wrote:

    Thanks for explaining. If this is so, it sounds... unscalable.
    How so?
    You have to inflate your cache anew from DB in every transaction. You don't have any data when you start.

    However I don't think you are right in your assessment. Googling "Hibernate second level cache" shows that its scope goes beyond a single session. And hence my original question - how do they reconcile second level cache presence and the promise of 100% data consistency. My answer is that they don't. So their bigger argument about data consistency is moot.

    Andrus
  • Andrus Adamchik at Mar 30, 2012 at 3:05 pm
    Let me try to think how to better present my point. I'll try to get back in a few days.
    On Mar 30, 2012, at 5:34 PM, Joe Baldwin wrote:

    Andrus,

    I am pretty smart, but I have NO idea what you just said, :) I would really like to understand your argument as it sounds like something that might be important to my project. Do you have an analysis somewhere I read up on this?

    Thanks
    Joe

    On Mar 30, 2012, at 10:12 AM, Andrus Adamchik wrote:

    On Mar 30, 2012, at 5:01 PM, Durchholz, Joachim wrote:

    Thanks for explaining. If this is so, it sounds... unscalable.
    How so?
    You have to inflate your cache anew from DB in every transaction. You don't have any data when you start.

    However I don't think you are right in your assessment. Googling "Hibernate second level cache" shows that its scope goes beyond a single session. And hence my original question - how do they reconcile second level cache presence and the promise of 100% data consistency. My answer is that they don't. So their bigger argument about data consistency is moot.

    Andrus
  • Durchholz, Joachim at Mar 30, 2012 at 2:37 pm

    On Mar 30, 2012, at 5:01 PM, Durchholz, Joachim wrote:

    Thanks for explaining. If this is so, it sounds... unscalable.
    How so?
    You have to inflate your cache anew from DB in every transaction.
    You don't have any data when you start.
    Sure, that's unavoidable if you want to do optimistic locking.
    However I don't think you are right in your assessment. Googling
    "Hibernate second level cache" shows that its scope goes beyond
    a single session.
    Right... I was mislead by statements in other parts of the Hibernate literature I'm using.
    That cache can be controlled on a per-table basis: switched off for data that never must be stale (financial records), switched on for read-only data (configuration etc.)
    Quote Bauer/King: "... the second-level cache can be dangerous in systems that share the database with other writing applications." Hear, hear.

    They have four levels
    And hence my original question - how do they reconcile second
    level cache presence and the promise of 100% data consistency.
    It's the programmer's responsibility to decide what caching strategy to use for what table, it seems. They offer
    - "transactional": cache only within a transaction (J2EE only)
    - "read-write": detect stale data via timestamps
    - "nonstrict read-write": no guarantees, use a timeout
    - "read-only": cache is never updated

    Second-level caches are pluggable, Hibernate can support EHCache, OSCache, SwarmCache and JBossCache. Not all caches support all strategies - maybe that's why I never considered that "a part of Hibernate".
    My answer is that they don't. So their bigger argument about
    data consistency is moot.
    Well, Hibernate is a lot about high promises and 95% delivery :-)
    Though, in this particular area, I don't think it's possible to do much better. If you want to be sure nobody altered data that you're not writing, you need to hit the database and have a rather scary performance penalty to pay. The only way out that I can think about that is that the programmer specifies all the data dependencies, including the implicit ones; then the ORM can restrict the staleness checking to those objects that the changed objects might depend on.
    It would be the Right Thing To Do, but it would be hard to implement and fragile in practical usage, so I doubt it will be done.
  • Andrus Adamchik at Mar 30, 2012 at 2:55 pm

    On Mar 30, 2012, at 5:37 PM, Durchholz, Joachim wrote:

    You have to inflate your cache anew from DB in every transaction.
    You don't have any data when you start.
    Sure, that's unavoidable if you want to do optimistic locking.
    You can do optimistic locking with cached data just as well. It doesn't have to come from the same transaction as your update. That's the whole point of it.

    Andrus
  • Durchholz, Joachim at Apr 2, 2012 at 10:04 am

    You have to inflate your cache anew from DB in every transaction.
    You don't have any data when you start.
    Sure, that's unavoidable if you want to do optimistic locking.
    You can do optimistic locking with cached data just as well. It
    doesn't have to come from the same transaction as your update.
    That's the whole point of it.
    Agreed for the records that are being written back.

    However, there are records that have indirect dependencies. Stuff like updates to child records of which the parent record has gone away. Constraints that are not (portably or easily) expressible, such as rows covering contiguous ranges in their START_PERIOD and END_PERIOD fields. Configuration data that describes valid values, process A reduces the valid range, process B has the configuration in cache and validates against a stale configuration.
    This kind of stuff can be handled by either reloading everything on every application transaction. That's Hibernate's standard mode of operation (if you don't use a second-level cache, which is the default). Or by explicit coding. Or by letting application programmers specify each and every data dependency, and having the ORM detect changes not just in the records being updated but also changes in all records that these updates might depend on.
  • Joe Baldwin at Mar 30, 2012 at 1:40 pm
    About this comment:
    On Mar 30, 2012, at 8:56 AM, Durchholz, Joachim wrote:

    Cayenne doesn't care about staleness. It's the application's task to ensure that Pojo networks are updated to the current DB state at the beginning of an application-side transaction. If data isn't available yet, just load it - and accept the risk that the application may now be working with partly stale, partly current data.
    Are you sure that this is correct? (Note: I have a lot on my plate and cannot re-do some of my tests). I have a rather substantial webapp, in which I have modified database data via both Cayenne and directly via a DBMS Client (bypassing Cayenne). And in the critical data, Cayenne is able to present the DBClient modified data immediately. (I have another table in which this does not happen, but I think I designed it that way, and will have to get back to you on this).

    For the most part, I have seen that the *default* Cayenne behavior handles the "stale" issue pretty well. (This is, if changing data directly in the database, and then having Cayenne immediately display it via a webpage is an appropriate black-box test)

    I have seen some oddness with deleting objects via Cayenne, but I presumed that was due to me missing some refresh step

    But if you have a different test, please let me know, because this is important to my project.
    Joe
  • Durchholz, Joachim at Mar 30, 2012 at 1:53 pm

    Cayenne doesn't care about staleness. It's the application's
    task to ensure that Pojo networks are updated to the current
    DB state at the beginning of an application-side transaction.
    If data isn't available yet, just load it - and accept the
    risk that the application may now be working with partly
    stale, partly current data.
    Are you sure that this is correct?
    I'm not, I'm just inferring that from the fact that
    a) Cayenne is recreating connections as needed, so it cannot rely on transactional repeatable-read properties and
    b) assuming that rechecking all cached records for being up-to-date whenever anything else is loaded or stored.
    And in the critical data, Cayenne is able to present the
    DBClient modified data immediately.
    This may be a side effect of having a webapp.
    It might be reloading all data on each request (that's what webapps often do). Or it might be refreshing all relevant data on each request.
    For the most part, I have seen that the *default* Cayenne
    behavior handles the "stale" issue pretty well. (This is,
    if changing data directly in the database, and then having
    Cayenne immediately display it via a webpage is an
    appropriate black-box test)
    If that works without explicit programming, that would be awesome!
    But how would Cayenne achieve that and still have reasonable performance?
  • Joe Baldwin at Mar 30, 2012 at 3:17 pm

    OK, I am getting confused as to the subject that we are arguing. My interest is specifically with the thesis and conclusion:

    Cayenne doesn't care about staleness. ... If data isn't available yet, just load it - and accept the risk that the application may now be working with partly stale, partly current data.

    My comment (with warning that I have not made rigorous tests), is that if Cayenne is recognizing data that has been externally changed (i.e. not via Cayenne front door). If it can do this, then it does seem to have supporting behavior for addressing "staleness". What the details of that behavior are, I do not know. It does seem that the behavior is present though.

    Am I missing something?
    Joe




    On Mar 30, 2012, at 9:53 AM, Durchholz, Joachim wrote:

    Cayenne doesn't care about staleness. It's the application's
    task to ensure that Pojo networks are updated to the current
    DB state at the beginning of an application-side transaction.
    If data isn't available yet, just load it - and accept the
    risk that the application may now be working with partly
    stale, partly current data.
    Are you sure that this is correct?
    I'm not, I'm just inferring that from the fact that
    a) Cayenne is recreating connections as needed, so it cannot rely on transactional repeatable-read properties and
    b) assuming that rechecking all cached records for being up-to-date whenever anything else is loaded or stored.
    And in the critical data, Cayenne is able to present the
    DBClient modified data immediately.
    This may be a side effect of having a webapp.
    It might be reloading all data on each request (that's what webapps often do). Or it might be refreshing all relevant data on each request.
    For the most part, I have seen that the *default* Cayenne
    behavior handles the "stale" issue pretty well. (This is,
    if changing data directly in the database, and then having
    Cayenne immediately display it via a webpage is an
    appropriate black-box test)
    If that works without explicit programming, that would be awesome!
    But how would Cayenne achieve that and still have reasonable performance?
  • Michael Gentry at Mar 30, 2012 at 4:52 pm
    Hi Joe,

    It mainly sounds like you care about optimistic locking. Cayenne can
    use whichever columns you select to test for external changes upon an
    UPDATE. As for faulting data into memory, Cayenne will get the
    freshest data the DB has at that point, excluding any pending
    transactional changes. (Most databases will not make pending
    updates/inserts/deletes in another transaction visible to your
    transaction.)

    mrg

    On Fri, Mar 30, 2012 at 11:16 AM, Joe Baldwin wrote:
    OK, I am getting confused as to the subject that we are arguing.  My interest is specifically with the thesis and conclusion:
    Cayenne doesn't care about staleness. ... If data isn't available yet, just load it - and accept the risk that the application may now be working with partly stale, partly current data.

    My comment (with warning that I have not made rigorous tests), is that if Cayenne is recognizing data that has been externally changed (i.e. not via Cayenne front door). If it can do this, then it does seem to have supporting behavior for addressing "staleness". What the details of that behavior are, I do not know.  It does seem that the behavior is present though.

    Am I missing something?
    Joe




    On Mar 30, 2012, at 9:53 AM, Durchholz, Joachim wrote:

    Cayenne doesn't care about staleness. It's the application's
    task to ensure that Pojo networks are updated to the current
    DB state at the beginning of an application-side transaction.
    If data isn't available yet, just load it - and accept the
    risk that the application may now be working with partly
    stale, partly current data.
    Are you sure that this is correct?
    I'm not, I'm just inferring that from the fact that
    a) Cayenne is recreating connections as needed, so it cannot rely on transactional repeatable-read properties and
    b) assuming that rechecking all cached records for being up-to-date whenever anything else is loaded or stored.
    And in the critical data, Cayenne is able to present the
    DBClient modified data immediately.
    This may be a side effect of having a webapp.
    It might be reloading all data on each request (that's what webapps often do). Or it might be refreshing all relevant data on each request.
    For the most part, I have seen that the *default* Cayenne
    behavior handles the "stale" issue pretty well.  (This is,
    if changing data directly in the database, and then having
    Cayenne immediately display it via a webpage is an
    appropriate black-box test)
    If that works without explicit programming, that would be awesome!
    But how would Cayenne achieve that and still have reasonable performance?
  • Joe Baldwin at Mar 30, 2012 at 6:01 pm
    Hi Michael,

    I just looked up the def of Optimistic Locking and it forwarded me to Optimistic Concurrency Control (so I am not sure of the distinction just yet). But I *think* that the behavior that I have seen in my webapp would be your implementation of optimistic locking.

    RE: "As for faulting data into memory, Cayenne will get the freshest data the DB has at that point, excluding any pending transactional changes."

    I think that this addresses our side-discussion about whether Cayenne "cares about stale data". My testing seemed to indicate that it does "care" (aka provide behavior that ensures that the most recent DBMS managed data is represented). And yes, my test assumed that the test data was in fact committed (in this case by an independent MySQL client not associated with Cayenne).

    So if this is all true, then I was interested in Joachim's comment (as I understand it), that suggests this might not be a sustainable method for performance (I presume in the context of scaling data sets).

    So from another point of view: my conception is that you have a subset of the Relational data in hollow data objects (for performance reasons). So to maintain both performance, low memory usage, and data integrity - do you just keep the object reference and modify timestamp, and then verify these very quickly - or is there a slicker way of doing this?

    Thanks
    Joe

    On Mar 30, 2012, at 12:51 PM, Michael Gentry wrote:

    Hi Joe,

    It mainly sounds like you care about optimistic locking. Cayenne can
    use whichever columns you select to test for external changes upon an
    UPDATE. As for faulting data into memory, Cayenne will get the
    freshest data the DB has at that point, excluding any pending
    transactional changes. (Most databases will not make pending
    updates/inserts/deletes in another transaction visible to your
    transaction.)

    mrg

    On Fri, Mar 30, 2012 at 11:16 AM, Joe Baldwin wrote:
    OK, I am getting confused as to the subject that we are arguing. My interest is specifically with the thesis and conclusion:
    Cayenne doesn't care about staleness. ... If data isn't available yet, just load it - and accept the risk that the application may now be working with partly stale, partly current data.

    My comment (with warning that I have not made rigorous tests), is that if Cayenne is recognizing data that has been externally changed (i.e. not via Cayenne front door). If it can do this, then it does seem to have supporting behavior for addressing "staleness". What the details of that behavior are, I do not know. It does seem that the behavior is present though.

    Am I missing something?
    Joe




    On Mar 30, 2012, at 9:53 AM, Durchholz, Joachim wrote:

    Cayenne doesn't care about staleness. It's the application's
    task to ensure that Pojo networks are updated to the current
    DB state at the beginning of an application-side transaction.
    If data isn't available yet, just load it - and accept the
    risk that the application may now be working with partly
    stale, partly current data.
    Are you sure that this is correct?
    I'm not, I'm just inferring that from the fact that
    a) Cayenne is recreating connections as needed, so it cannot rely on transactional repeatable-read properties and
    b) assuming that rechecking all cached records for being up-to-date whenever anything else is loaded or stored.
    And in the critical data, Cayenne is able to present the
    DBClient modified data immediately.
    This may be a side effect of having a webapp.
    It might be reloading all data on each request (that's what webapps often do). Or it might be refreshing all relevant data on each request.
    For the most part, I have seen that the *default* Cayenne
    behavior handles the "stale" issue pretty well. (This is,
    if changing data directly in the database, and then having
    Cayenne immediately display it via a webpage is an
    appropriate black-box test)
    If that works without explicit programming, that would be awesome!
    But how would Cayenne achieve that and still have reasonable performance?
  • Sheldon at Apr 2, 2012 at 8:19 am
    What I mean is,

    if I have a Table with n columns (col1, col2, col3 ...) and want load only
    the value of col1 and col3 (without loading col2 and the others).
    Is this example possible?

    Sheldon

    --
    View this message in context: http://cayenne.195.n3.nabble.com/lazy-loading-tp3863908p3877037.html
    Sent from the Cayenne - User mailing list archive at Nabble.com.
  • Andrew Lindesay at Apr 2, 2012 at 8:53 am
    Hi Sheldon;

    You can just create an EJBQLQuery that extracts those specific columns
    (expressed as entity attributes' names) and then run the query and
    you'll pull back that data. A crude example of such a query;

    "SELECT o." + Foo.CODE_PROPERTY+" FROM "+Foo.class.getSimpleName()+" o
    WHERE o."......

    Is that what you mean?

    Regards;
    On 2/04/12 8:18 PM, Sheldon wrote:
    What I mean is,

    if I have a Table with n columns (col1, col2, col3 ...) and want load only
    the value of col1 and col3 (without loading col2 and the others).
    Is this example possible?

    Sheldon

    --
    View this message in context: http://cayenne.195.n3.nabble.com/lazy-loading-tp3863908p3877037.html
    Sent from the Cayenne - User mailing list archive at Nabble.com.

    --
    Andrew Lindesay
    www.silvereye.co.nz
  • Sheldon at Apr 10, 2012 at 3:18 pm
    Hi Andrew,

    can I do this programmatically (without using SQL's)?

    Sheldon

    --
    View this message in context: http://cayenne.195.n3.nabble.com/lazy-loading-tp3863908p3899950.html
    Sent from the Cayenne - User mailing list archive at Nabble.com.
  • Michael Gentry at Mar 28, 2012 at 2:21 pm
    Hi Joachim, et al,

    If you need to prefetch some relationships to improve performance, it
    is usually pretty simple to add a prefetch to your query. Here is the
    documentation page if you are curious:

    http://cayenne.apache.org/doc/prefetching.html


    mrg


    On Wed, Mar 28, 2012 at 10:04 AM, Durchholz, Joachim
    wrote:
    I think what Michael was saying was, that the answer is that 'lazy loading
    of data object relationship data is supported and is the default mechanism'.
    That's what I read, too.
    (In fact this is one of the main strengths of Cayenne in my opinion)
    On a tangent, I don't think this can be advertised as a special strength of Cayenne.
    Think about it: Any ORM that does not do by-default lazy association loading will quickly find itself loading the entire database. If it wasn't built into the ORM right from the beginning, the ORM is essentially useless and will either die or get that feature added ASAP.

    The more interesting comparison would be how easily an application developer could specify when to load eagerly.
    (Not that I'm in a position to actually do such a comparison. ;-) )

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
groupuser @
categoriescayenne
postedMar 28, '12 at 8:27a
activeApr 10, '12 at 3:18p
posts39
users10
websitecayenne.apache.org

People

Translate

site design / logo © 2022 Grokbase