Re: [appengine-java] [JDO Paging] Getting a cursor BEFORE the end of results

2010-05-07 Thread Jeff Schnitzer
This depends on what you mean by lazily load the entity.  There are
at least three possible interpretations of lazy loading:

1) Lazily fetching data across the wire
2) Lazily converting from protocol buffers to Entity objects
3) Lazily translating Entity objects to Java POJOs

The first two steps are encapsulated within the Low-Level API, the
third step is part of JDO/Objectify/etc.

I know that when you issue a query, the results are batched in chunks
of a size that you can control.  #1 and #2 are done together; the data
is pulled across the wire into materialized Entity objects in
increments of the batch size.

Objectify does #3 at the last possible moment; if you do not call
next() and retrieve a POJO entity, the POJO will not be instantiated.
You can call hasNext() to determine the existence of another page and
this will not create a POJO - however, the Low-Level API will create
the Entity.

In practice, it's hard to imagine that this matters unless your page
size is something like 2.  If you have 20 elements on a page, the
worst-case scenario is that fetching 21 will add 5% to the cost of the
query.  That's not much.

You can do what you want with Objectify and I suspect you can do what
you want with JDO, just don't use getResultList().  Get an actual
QueryResultIterator so the getCursor() call will return the correct
location.

Jeff

On Thu, May 6, 2010 at 8:48 PM, Chau Huynh cmhu...@gmail.com wrote:
 Hi Jeff,

 With JPA I will need to excute getResultList() to get a collection
 http://java.sun.com/javaee/5/docs/api/javax/persistence/Query.html#getResultList()
 Somehow org.datanucleus.store.appengine.query.getCursor(Iterator? iter)
 can not get the cursor in the middle of my iterator, a null value is
 returned in sample code below.
 I guess getCursor() has something to do with the List returned.

 EntityManager em =
 Query query = em.createQuery(queryString);
 query.setMaxResults(pageSize + 1);
 em.getTransaction().begin();
 IteratorTestEntity iterator = query.getResultList().iterator();
 ListTestEntity list = new ArrayListTestEntity();
 for (int i = 0; (i  pageSize)  iterator.hasNext(); i++) {
     list.add(iterator.next());
 }
 Cursor cursor = JPACursorHelper.getCursor(iterator);
 // assert iterator.hasNext() == true and cursor == null
 em.getTransaction().rollback();

 Just my curious:
 if I'm able to iterate through the result (using
 com.google.appengine.api.datastore.QueryResultIteratorT)
 is it true that each iterator.hasNext() will lazily load entity from the
 data store?
 My concern is it might cost me more time that way than using
 Query.getResultList(). Please advise.

 Thank you.

 On Fri, May 7, 2010 at 2:24 AM, Jeff Schnitzer j...@infohazard.org wrote:

 I'm a little confused by this.  Why doesn't the OP's approach work?

 1) Create query, fetch with limit of 21 items
 2) Iterate through 20 items
 3) Get cursor to be used for next page (if necessary)
 4) Iterate to 21st item just to check for existence

 Why won't this work?  The documentation seems to imply that this is
 how cursors work...

 Jeff

 On Thu, May 6, 2010 at 1:03 AM, Ikai L (Google) ika...@google.com wrote:
  This is a datastore limitation and not related to JDO/JPA, so you won't
  be
  able to do this in Objectify either (you can look at the low-level API,
  it
  doesn't provide this functionality). I believe I saw an issue in the
  issues
  tracker about creating cursors from arbitrary locations.
 
  --
  You received this message because you are subscribed to the Google
  Groups
  Google App Engine for Java group.
  To post to this group, send email to
  google-appengine-j...@googlegroups.com.
  To unsubscribe from this group, send email to
  google-appengine-java+unsubscr...@googlegroups.com.
  For more options, visit this group at
  http://groups.google.com/group/google-appengine-java?hl=en.
 

 --
 You received this message because you are subscribed to the Google Groups
 Google App Engine for Java group.
 To post to this group, send email to
 google-appengine-j...@googlegroups.com.
 To unsubscribe from this group, send email to
 google-appengine-java+unsubscr...@googlegroups.com.
 For more options, visit this group at
 http://groups.google.com/group/google-appengine-java?hl=en.


 --
 You received this message because you are subscribed to the Google Groups
 Google App Engine for Java group.
 To post to this group, send email to google-appengine-j...@googlegroups.com.
 To unsubscribe from this group, send email to
 google-appengine-java+unsubscr...@googlegroups.com.
 For more options, visit this group at
 http://groups.google.com/group/google-appengine-java?hl=en.


-- 
You received this message because you are subscribed to the Google Groups 
Google App Engine for Java group.
To post to this group, send email to google-appengine-j...@googlegroups.com.
To unsubscribe from this group, send email to 
google-appengine-java+unsubscr...@googlegroups.com.
For more options, visit this group at 

Re: [appengine-java] [JDO Paging] Getting a cursor BEFORE the end of results

2010-05-07 Thread Chau Huynh
Thank you very much, Jeff. I'm so happy to learn those.
I will definitely try the suggested library.
Thanks.

On Sat, May 8, 2010 at 4:15 AM, Jeff Schnitzer j...@infohazard.org wrote:

 This depends on what you mean by lazily load the entity.  There are
 at least three possible interpretations of lazy loading:

 1) Lazily fetching data across the wire
 2) Lazily converting from protocol buffers to Entity objects
 3) Lazily translating Entity objects to Java POJOs

 The first two steps are encapsulated within the Low-Level API, the
 third step is part of JDO/Objectify/etc.

 I know that when you issue a query, the results are batched in chunks
 of a size that you can control.  #1 and #2 are done together; the data
 is pulled across the wire into materialized Entity objects in
 increments of the batch size.

 Objectify does #3 at the last possible moment; if you do not call
 next() and retrieve a POJO entity, the POJO will not be instantiated.
 You can call hasNext() to determine the existence of another page and
 this will not create a POJO - however, the Low-Level API will create
 the Entity.

 In practice, it's hard to imagine that this matters unless your page
 size is something like 2.  If you have 20 elements on a page, the
 worst-case scenario is that fetching 21 will add 5% to the cost of the
 query.  That's not much.

 You can do what you want with Objectify and I suspect you can do what
 you want with JDO, just don't use getResultList().  Get an actual
 QueryResultIterator so the getCursor() call will return the correct
 location.

 Jeff

 On Thu, May 6, 2010 at 8:48 PM, Chau Huynh cmhu...@gmail.com wrote:
  Hi Jeff,
 
  With JPA I will need to excute getResultList() to get a collection
 
 http://java.sun.com/javaee/5/docs/api/javax/persistence/Query.html#getResultList()http://java.sun.com/javaee/5/docs/api/javax/persistence/Query.html#getResultList%28%29
  Somehow org.datanucleus.store.appengine.query.getCursor(Iterator? iter)
  can not get the cursor in the middle of my iterator, a null value is
  returned in sample code below.
  I guess getCursor() has something to do with the List returned.
 
  EntityManager em =
  Query query = em.createQuery(queryString);
  query.setMaxResults(pageSize + 1);
  em.getTransaction().begin();
  IteratorTestEntity iterator = query.getResultList().iterator();
  ListTestEntity list = new ArrayListTestEntity();
  for (int i = 0; (i  pageSize)  iterator.hasNext(); i++) {
  list.add(iterator.next());
  }
  Cursor cursor = JPACursorHelper.getCursor(iterator);
  // assert iterator.hasNext() == true and cursor == null
  em.getTransaction().rollback();
 
  Just my curious:
  if I'm able to iterate through the result (using
  com.google.appengine.api.datastore.QueryResultIteratorT)
  is it true that each iterator.hasNext() will lazily load entity from the
  data store?
  My concern is it might cost me more time that way than using
  Query.getResultList(). Please advise.
 
  Thank you.
 
  On Fri, May 7, 2010 at 2:24 AM, Jeff Schnitzer j...@infohazard.org
 wrote:
 
  I'm a little confused by this.  Why doesn't the OP's approach work?
 
  1) Create query, fetch with limit of 21 items
  2) Iterate through 20 items
  3) Get cursor to be used for next page (if necessary)
  4) Iterate to 21st item just to check for existence
 
  Why won't this work?  The documentation seems to imply that this is
  how cursors work...
 
  Jeff
 
  On Thu, May 6, 2010 at 1:03 AM, Ikai L (Google) ika...@google.com
 wrote:
   This is a datastore limitation and not related to JDO/JPA, so you
 won't
   be
   able to do this in Objectify either (you can look at the low-level
 API,
   it
   doesn't provide this functionality). I believe I saw an issue in the
   issues
   tracker about creating cursors from arbitrary locations.
  
   --
   You received this message because you are subscribed to the Google
   Groups
   Google App Engine for Java group.
   To post to this group, send email to
   google-appengine-j...@googlegroups.com.
   To unsubscribe from this group, send email to
   google-appengine-java+unsubscr...@googlegroups.comgoogle-appengine-java%2bunsubscr...@googlegroups.com
 .
   For more options, visit this group at
   http://groups.google.com/group/google-appengine-java?hl=en.
  
 
  --
  You received this message because you are subscribed to the Google
 Groups
  Google App Engine for Java group.
  To post to this group, send email to
  google-appengine-j...@googlegroups.com.
  To unsubscribe from this group, send email to
  google-appengine-java+unsubscr...@googlegroups.comgoogle-appengine-java%2bunsubscr...@googlegroups.com
 .
  For more options, visit this group at
  http://groups.google.com/group/google-appengine-java?hl=en.
 
 
  --
  You received this message because you are subscribed to the Google Groups
  Google App Engine for Java group.
  To post to this group, send email to
 google-appengine-j...@googlegroups.com.
  To unsubscribe from this group, send email to
  

Re: [appengine-java] [JDO Paging] Getting a cursor BEFORE the end of results

2010-05-06 Thread Ikai L (Google)
This is a datastore limitation and not related to JDO/JPA, so you won't be
able to do this in Objectify either (you can look at the low-level API, it
doesn't provide this functionality). I believe I saw an issue in the issues
tracker about creating cursors from arbitrary locations.

-- 
You received this message because you are subscribed to the Google Groups 
Google App Engine for Java group.
To post to this group, send email to google-appengine-j...@googlegroups.com.
To unsubscribe from this group, send email to 
google-appengine-java+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/google-appengine-java?hl=en.



Re: [appengine-java] [JDO Paging] Getting a cursor BEFORE the end of results

2010-05-06 Thread Jeff Schnitzer
I'm a little confused by this.  Why doesn't the OP's approach work?

1) Create query, fetch with limit of 21 items
2) Iterate through 20 items
3) Get cursor to be used for next page (if necessary)
4) Iterate to 21st item just to check for existence

Why won't this work?  The documentation seems to imply that this is
how cursors work...

Jeff

On Thu, May 6, 2010 at 1:03 AM, Ikai L (Google) ika...@google.com wrote:
 This is a datastore limitation and not related to JDO/JPA, so you won't be
 able to do this in Objectify either (you can look at the low-level API, it
 doesn't provide this functionality). I believe I saw an issue in the issues
 tracker about creating cursors from arbitrary locations.

 --
 You received this message because you are subscribed to the Google Groups
 Google App Engine for Java group.
 To post to this group, send email to google-appengine-j...@googlegroups.com.
 To unsubscribe from this group, send email to
 google-appengine-java+unsubscr...@googlegroups.com.
 For more options, visit this group at
 http://groups.google.com/group/google-appengine-java?hl=en.


-- 
You received this message because you are subscribed to the Google Groups 
Google App Engine for Java group.
To post to this group, send email to google-appengine-j...@googlegroups.com.
To unsubscribe from this group, send email to 
google-appengine-java+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/google-appengine-java?hl=en.



Re: [appengine-java] [JDO Paging] Getting a cursor BEFORE the end of results

2010-05-06 Thread Chau Huynh
Hi Jeff,

With JPA I will need to excute getResultList() to get a collection
http://java.sun.com/javaee/5/docs/api/javax/persistence/Query.html#getResultList()
Somehow org.datanucleus.store.appengine.query.getCursor(Iterator? iter)
can not get the cursor in the middle of my iterator, a null value is
returned in sample code below.
I guess getCursor() has something to do with the List returned.

EntityManager em =
Query query = em.createQuery(queryString);
query.setMaxResults(pageSize + 1);
em.getTransaction().begin();
IteratorTestEntity iterator = query.getResultList().iterator();
ListTestEntity list = new ArrayListTestEntity();
for (int i = 0; (i  pageSize)  iterator.hasNext(); i++) {
list.add(iterator.next());
}
Cursor cursor = JPACursorHelper.getCursor(iterator);
// assert iterator.hasNext() == true and cursor == null
em.getTransaction().rollback();

Just my curious:
if I'm able to iterate through the result (using
com.google.appengine.api.datastore.QueryResultIteratorT)
is it true that each iterator.hasNext() will lazily load entity from the
data store?
My concern is it might cost me more time that way than using
Query.getResultList(). Please advise.

Thank you.

On Fri, May 7, 2010 at 2:24 AM, Jeff Schnitzer j...@infohazard.org wrote:

 I'm a little confused by this.  Why doesn't the OP's approach work?

 1) Create query, fetch with limit of 21 items
 2) Iterate through 20 items
 3) Get cursor to be used for next page (if necessary)
 4) Iterate to 21st item just to check for existence

 Why won't this work?  The documentation seems to imply that this is
 how cursors work...

 Jeff

 On Thu, May 6, 2010 at 1:03 AM, Ikai L (Google) ika...@google.com wrote:
  This is a datastore limitation and not related to JDO/JPA, so you won't
 be
  able to do this in Objectify either (you can look at the low-level API,
 it
  doesn't provide this functionality). I believe I saw an issue in the
 issues
  tracker about creating cursors from arbitrary locations.
 
  --
  You received this message because you are subscribed to the Google Groups
  Google App Engine for Java group.
  To post to this group, send email to
 google-appengine-j...@googlegroups.com.
  To unsubscribe from this group, send email to
  google-appengine-java+unsubscr...@googlegroups.comgoogle-appengine-java%2bunsubscr...@googlegroups.com
 .
  For more options, visit this group at
  http://groups.google.com/group/google-appengine-java?hl=en.
 

 --
 You received this message because you are subscribed to the Google Groups
 Google App Engine for Java group.
 To post to this group, send email to
 google-appengine-j...@googlegroups.com.
 To unsubscribe from this group, send email to
 google-appengine-java+unsubscr...@googlegroups.comgoogle-appengine-java%2bunsubscr...@googlegroups.com
 .
 For more options, visit this group at
 http://groups.google.com/group/google-appengine-java?hl=en.



-- 
You received this message because you are subscribed to the Google Groups 
Google App Engine for Java group.
To post to this group, send email to google-appengine-j...@googlegroups.com.
To unsubscribe from this group, send email to 
google-appengine-java+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/google-appengine-java?hl=en.



Re: [appengine-java] [JDO Paging] Getting a cursor BEFORE the end of results

2010-05-06 Thread Chau Huynh
There's 1 typo in my message, please read

org.datanucleus.store.appengine.query.CursorHelper.getCursor(Iterator?
iter)

Thanks

On Fri, May 7, 2010 at 10:48 AM, Chau Huynh cmhu...@gmail.com wrote:

 Hi Jeff,

 With JPA I will need to excute getResultList() to get a collection

 http://java.sun.com/javaee/5/docs/api/javax/persistence/Query.html#getResultList()http://java.sun.com/javaee/5/docs/api/javax/persistence/Query.html#getResultList%28%29
 Somehow org.datanucleus.store.appengine.query.getCursor(Iterator? iter)
 can not get the cursor in the middle of my iterator, a null value is
 returned in sample code below.
 I guess getCursor() has something to do with the List returned.

 EntityManager em =
 Query query = em.createQuery(queryString);
 query.setMaxResults(pageSize + 1);
 em.getTransaction().begin();
 IteratorTestEntity iterator = query.getResultList().iterator();
 ListTestEntity list = new ArrayListTestEntity();
 for (int i = 0; (i  pageSize)  iterator.hasNext(); i++) {
 list.add(iterator.next());
 }
 Cursor cursor = JPACursorHelper.getCursor(iterator);
 // assert iterator.hasNext() == true and cursor == null
 em.getTransaction().rollback();

 Just my curious:
 if I'm able to iterate through the result (using
 com.google.appengine.api.datastore.QueryResultIteratorT)
 is it true that each iterator.hasNext() will lazily load entity from the
 data store?
 My concern is it might cost me more time that way than using
 Query.getResultList(). Please advise.

 Thank you.


 On Fri, May 7, 2010 at 2:24 AM, Jeff Schnitzer j...@infohazard.orgwrote:

 I'm a little confused by this.  Why doesn't the OP's approach work?

 1) Create query, fetch with limit of 21 items
 2) Iterate through 20 items
 3) Get cursor to be used for next page (if necessary)
 4) Iterate to 21st item just to check for existence

 Why won't this work?  The documentation seems to imply that this is
 how cursors work...

 Jeff

 On Thu, May 6, 2010 at 1:03 AM, Ikai L (Google) ika...@google.com
 wrote:
  This is a datastore limitation and not related to JDO/JPA, so you won't
 be
  able to do this in Objectify either (you can look at the low-level API,
 it
  doesn't provide this functionality). I believe I saw an issue in the
 issues
  tracker about creating cursors from arbitrary locations.
 
  --
  You received this message because you are subscribed to the Google
 Groups
  Google App Engine for Java group.
  To post to this group, send email to
 google-appengine-j...@googlegroups.com.
  To unsubscribe from this group, send email to
  google-appengine-java+unsubscr...@googlegroups.comgoogle-appengine-java%2bunsubscr...@googlegroups.com
 .
  For more options, visit this group at
  http://groups.google.com/group/google-appengine-java?hl=en.
 

 --
 You received this message because you are subscribed to the Google Groups
 Google App Engine for Java group.
 To post to this group, send email to
 google-appengine-j...@googlegroups.com.
 To unsubscribe from this group, send email to
 google-appengine-java+unsubscr...@googlegroups.comgoogle-appengine-java%2bunsubscr...@googlegroups.com
 .
 For more options, visit this group at
 http://groups.google.com/group/google-appengine-java?hl=en.




-- 
You received this message because you are subscribed to the Google Groups 
Google App Engine for Java group.
To post to this group, send email to google-appengine-j...@googlegroups.com.
To unsubscribe from this group, send email to 
google-appengine-java+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/google-appengine-java?hl=en.



Re: [appengine-java] [JDO Paging] Getting a cursor BEFORE the end of results

2010-05-06 Thread Yasuo Higa
Hi James and Jeff,

 1) Create query, fetch with limit of 21 items
 2) Iterate through 20 items
 3) Get cursor to be used for next page (if necessary)
 4) Iterate to 21st item just to check for existence

This is exactly what Slim3 supports.
http://sites.google.com/site/slim3appengine/slim3-datastore/queries-and-indexes/query-cursors

The following code may help you, see 236 lines(ModelQuery#asQueryResultList):
http://code.google.com/p/slim3/source/browse/trunk/slim3/src/main/java/org/slim3/datastore/ModelQuery.java

Hope this helps,

Yasuo Higa

-- 
You received this message because you are subscribed to the Google Groups 
Google App Engine for Java group.
To post to this group, send email to google-appengine-j...@googlegroups.com.
To unsubscribe from this group, send email to 
google-appengine-java+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/google-appengine-java?hl=en.



[appengine-java] [JDO Paging] Getting a cursor BEFORE the end of results

2010-05-05 Thread James
I'm implementing some UI paging and trying to detect whether a record
exists beyond the current page (in order to show a more button).

I hoped to iterate over a result set of pageSize + 1, grabbing the
cursor as I pass the item @ pageSize, and then using the existence of
the last item to know there's more to be shown.  Unfortunately I can't
find a way to accomplish this using JDO.

JDOCursorHelper.getCursor(ListT) is documented to get the cursor for
the last item in the list, so that works as documented but doesn't
help me.

JDOCursorHelper.getCursor(IteratorT) seems to be what I need, but
every Iterator that I can find to pass to it causes it to return
null.  I've tried passing ((ListT)query.execute).iterator() as well
as ((QueryResult)query.execute).iterator() and both have the same
result.

Anyone know if there's a not-too-kludgy way to do this w/o requerying
the datastore for the additional item.  Or is it easier in Objectify
(I'm considering switching)?

Thanks much,

James

-- 
You received this message because you are subscribed to the Google Groups 
Google App Engine for Java group.
To post to this group, send email to google-appengine-j...@googlegroups.com.
To unsubscribe from this group, send email to 
google-appengine-java+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/google-appengine-java?hl=en.



Re: [appengine-java] [JDO Paging] Getting a cursor BEFORE the end of results

2010-05-05 Thread Chau Huynh
About JDO/JPA, I tried the same thing, and Google advised to make 2 calls:
the first one is your query,
the second one, which is a key-only  single item query so that it can be
cheap, to check if more data is available.
http://groups.google.com/group/google-appengine-java/browse_thread/thread/80f1a0314987f26b?pli=1

On Thu, May 6, 2010 at 12:18 AM, James jamesk...@gmail.com wrote:

 I'm implementing some UI paging and trying to detect whether a record
 exists beyond the current page (in order to show a more button).

 I hoped to iterate over a result set of pageSize + 1, grabbing the
 cursor as I pass the item @ pageSize, and then using the existence of
 the last item to know there's more to be shown.  Unfortunately I can't
 find a way to accomplish this using JDO.

 JDOCursorHelper.getCursor(ListT) is documented to get the cursor for
 the last item in the list, so that works as documented but doesn't
 help me.

 JDOCursorHelper.getCursor(IteratorT) seems to be what I need, but
 every Iterator that I can find to pass to it causes it to return
 null.  I've tried passing ((ListT)query.execute).iterator() as well
 as ((QueryResult)query.execute).iterator() and both have the same
 result.

 Anyone know if there's a not-too-kludgy way to do this w/o requerying
 the datastore for the additional item.  Or is it easier in Objectify
 (I'm considering switching)?

 Thanks much,

 James

 --
 You received this message because you are subscribed to the Google Groups
 Google App Engine for Java group.
 To post to this group, send email to
 google-appengine-j...@googlegroups.com.
 To unsubscribe from this group, send email to
 google-appengine-java+unsubscr...@googlegroups.comgoogle-appengine-java%2bunsubscr...@googlegroups.com
 .
 For more options, visit this group at
 http://groups.google.com/group/google-appengine-java?hl=en.



-- 
You received this message because you are subscribed to the Google Groups 
Google App Engine for Java group.
To post to this group, send email to google-appengine-j...@googlegroups.com.
To unsubscribe from this group, send email to 
google-appengine-java+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/google-appengine-java?hl=en.