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