I'm trying to find out if I'm using the @Version annotation properly
in my project.
I read the "code snippets that work" from Max Ross:
http://gae-java-persistence.blogspot.com/2009/10/optimistic-locking-with-version.html
...but perhaps there's a subtle detail I'm missing.

I have a class that gets frequent updates, and I query that class an
aweful lot (around 2-3 times per second, and yes: that is critical to
the application).

The issue I'm seeing is that when I query this object for an update, I
often get an outdated version, even though I've got the @Version
annotation on the class level.

I've not been able to duplicate the issue locally, however, I do see
it when I deploy my app.
I notice that the OPT_VERSION property in the datastore never seems to
change from "1".  Also, I notice that (occasionally, but repeatably)
the value of the bean that I read (for update checking) is a few
versions behind what it should be.  I can see this by executing a few
updates on a bean (sequentially, in different requests), and just
monitor the status of the bean (on 1 second intervals) in a different
browser.  To see the status, I just have a GWT page that sends a
request every second asking for the status of a given bean.  The issue
is visible via logging on the server side, so I know it's not just a
GWT async request getting lost and eventually finding it's way back to
me.

Here is a simplified version of the class:

@Version(strategy=VersionStrategy.VERSION_NUMBER)
@PersistenceCapable(identityType=IdentityType.APPLICATION)
public class Product extends BaseBean {

     @PrimaryKey
     @Persistent(valueStrategy=IdGeneratorStrategy.IDENTITY)
     Key id;

     @Persistent
     BigDecimal currentPrice;

     @Persistent
     Date bidStartDate;

     @Persistent
     Date bidEndDate;

     .... getters/setters
}

it's super class is BaseBean, it's just there to implement some
interfaces and provide a baseline equals implementation:
public abstract class BaseBean implements IsSerializable,
Serializable, Identifiable {
   ...
    public boolean equals(Object obj) {...}
    ....
}

here is the method that I'm using to query/update the bean:

public Product getUpdatedProduct(Key productId) {
     return readObject(Product.class, productId);
}

public void placeBid(Key productId, BigDecimal bidAmount) {
     //read object uses a dedicated PersistenceManager for reads
     Product product = readObject(Product.class, productId);
     BigDecimal oldPrice = product.getCurrentPrice();

     // update the price
     product.setCurrentPrice(oldPrice.add(bidAmount));

     // saves use a fresh PersistenceManager, so you have to detach or
you'll get an exception
     product = detatchCopy(product);

     saveObject(product);
}

public <T> T saveObject(T bean) {
      PersistenceManager pm = PMF.get();
      Transaction tx = pm.currentTransaction();

      try {
            tx.begin();
            bean = pm.makePersistent(bean);
            tx.commit();
     }
     catch(Exception e) {
           e.printStackTrace();
     }
     finally {
          wrapUpTransactionIfNeeded(pm, tx);
     }

     return bean;
}


I'll be happy to provide more details if needed, I'm sure I'm missing
something silly, I just don't know what it is.

Thanks in advance,
-bryce

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

Reply via email to