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 <[email protected]> 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 [email protected] To unsubscribe from this group, send email to [email protected] For more options, visit this group at http://groups.google.com/group/google-appengine-java?hl=en -~----------~----~----~----~------~----~------~--~---
