Maybe he forgot to precede it with the usual "if 
(em.getTransaction().isActive())"?


David Fuelling wrote:
> Hi Max,
> 
> I asked this question in the comments of your blog post, but I'll post
> it here as well for the "group" folks:
> 
> Why is the transaction rolled-back at the end of the each
> keysOfBooksPublishedBetween() function call?  Also, it is necessary to
> wrap the "get by key" query in a transaction, and if so why is that?
> 
> Thanks!
> 
> David
> 
> On Oct 6, 6:00 pm, Max Ross <maxr+appeng...@google.com> wrote:
>> Welcome to Episode 4 of JDO/JPA Snippets That Work.  Today we're going to
>> look at keys-only queries.
>>
>> Keys Only Queries
>>
>> If you use the low-level datastore api you may have noticed that the
>> com.google.appengine.api.datastore.Query class has a setKeysOnly() method.
>> If you call this method before you execute the query the datastore will
>> return com.google.appengine.api.datastore.Entity instances that have their
>> keys filled in but none of their properties.  This can reduce consumption of
>> your Datastore Data Received from API quota, especially if you've got some
>> large entities, but, more importantly, it can also reduce consumption of
>> your Datastore CPU Time quota.  How?  Well, if the fulfillment of your query
>> requires an index or a merge join your query actually executes in two
>> stages:  First it scans the index to find the keys of the entities that
>> match and then it issues additional scans to retrieve the entities uniquely
>> identified by the matching keys.  If your query is keys-only we can skip
>> that second step entirely.  That means faster queries!
>>
>> Now, JPA and JDO don't know anything about keys-only queries, but they do
>> give you the flexibility to either return your entire object or some subset
>> of the fields on your object.  If you construct this subset to only contain
>> the primary key of your object, the App Engine implementation of JPA and JDO
>> will use a keys-only query.  Let's look at some examples:
>>
>> JPA:
>> @Entity
>> public class Book {
>>     @Id
>>     @GeneratedValue(strategy=GenerationType.IDENTITY)
>>     private Key id;
>>
>>     private Date dateOfPublication;
>>
>>     // getters and setters
>>
>> }
>>
>> Now let's implement a method that returns the Keys of all Books published
>> betweeen 2 years (we'll assume someone else is creating and closing an
>> EntityManager named 'em' for us):
>>
>> public List<Key> keysOfBooksPublishedBetween(EntityManager em, Date from,
>> Date to) {
>>     em.getTransaction().begin();
>>     try {
>>         Query q = em.createQuery("select id from " + Book.class.getName()
>>             + " where dateOfPublication >= :from AND dateOfPublication <=
>> :to");
>>         q.setParameter("from", from);
>>         q.setParameter("to", to);
>>         return (List<Key>) q.getResultList();
>>     } finally {
>>         em.getTransaction().rollback();
>>     }
>>
>> }
>>
>> JDO:
>>
>> @PersistenceCapable(identityType = IdentityType.APPLICATION, detachable =
>> "true")
>> public class Book {
>>
>>     @PrimaryKey
>>     @Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
>>     private Key id;
>>
>>     private Date dateOfPublication;
>>
>>     // getters and setters
>>
>> }
>>
>> Now let's implement a method that returns the Keys of all Books published
>> betweeen 2 years (we'll assume someone else is creating and closing a
>> PersistenceManager named 'pm' for us):
>>
>> public List<Key> keysOfBooksPublishedBetween(PersistenceManager pm, Date
>> from, Date to) {
>>     pm.currentTransaction().begin();
>>     try {
>>         Query q = pm.newQuery("select id from " + Book.class.getName()
>>             + " where dateOfPublication >= :from && dateOfPublication <=
>> :to");
>>         return (List<Key>) q.execute(from, to);
>>     } finally {
>>         pm.currentTransaction().rollback();
>>     }}
>>
>> --------------------------------
>> Notice how we are only selecting the 'id' field from our Book class.  This
>> is crucial.  If you select any other fields your query will end up fetching
>> entire entities and the optimization will be lost.
>>
>> Max
> > 

--~--~---------~--~----~------------~-------~--~----~
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-java@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
-~----------~----~----~----~------~----~------~--~---

Reply via email to