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.