Hi Ashley, This isn't the way I would go about structuring this if I'm understanding the way you've set up your classes. There are a few issues right away that I see. For one, if you have a couple thousand Order children under the Account parent and you call getOrders() in your addOrder() method then you're pulling all that data from the datastore in to the application just to add a new order to the Account. So this will keep getting slower and slower as you add Orders to the Account and it looks like you've now reached the max, so that might be why it's worked up until now. Also, you are reducing the amount of concurrency that can take place on your Account class so if you are trying to have multiple orders that could be added to an Account simultaneously you're going to run in to contention issues. Stephen
On Mon, May 16, 2011 at 10:30 PM, Ashley Schroder <[email protected] > wrote: > I have a fairly simple App Engine Java app that has Accounts, Orders and > OrderItems - nothing crazy. > > Just in the last 12 hours I have started getting exceptions thrown out of > some fairly straight forward code that adds orders to accounts and then > saves them. > > I created a trivial testing servlet to replicate the issue, it looks like > this: > > public void doGet(HttpServletRequest req, HttpServletResponse resp) > throws IOException { > > String key = req.getParameter("key"); > > PersistenceManager pm = PMF.get().getPersistenceManager(); > Account account = pm.getObjectById(Account.class, > KeyFactory.stringToKey(key)); > > Order order = new Order(); > order.setExternalOrderID("ASHLEY-TESTING"); > > Item item = new Item(); > item.setSku("ASHLEY-WIDGET-A"); > item.setQuantity(2); > Item item2 = new Item(); > item2.setSku("ASHLEY-WIDGET-B"); > item2.setQuantity(2); > > order.addItem(item); > order.addItem(item2); > > account.addOrder(order); > order.setAccount(account); > pm.makePersistent(order); > pm.close(); > } > > addOrder is implemented as a pretty standard lazy init: > > public void addOrder(Order order) { > if (getOrders() == null) { > setOrders(new ArrayList<Order>()); > } > getOrders().add(order); > } > > The relevant parts of the entities: > > @PersistenceCapable > > public class Account { > > //... > > @Persistent(mappedBy="account") > @javax.jdo.annotations.Order(extensions = > @Extension(vendorName="datanucleus", key="list-ordering", value="startDate > desc")) > private List<Stats> stats; > > //... > > } > > and the Order has an account field: > > @Persistent > private Account account; > > > This code is failing on the `account.addOrder()` line. If it is run > directly in the browser it fails with DeadlineExceededException (after 30s) > and if I enqueue it to run via a task queue it fails with > DatastoreTimeoutException after a minute or two. It uses a truck load of CPU > time in the process. > > I would estimate that the Account would have fewer than 2000 Orders > children under it, each Order with 1-3 OrderItem children. > > My question is, why would this all of a sudden start failing it has worked > to add the 1000's of orders already in there. And have I missed something > vital? do I need to add indexes? could the data store really be this slow? > Am I abusing it, should I not have children relationships with this many > children - perhaps a set of keys would be a better approach? > > -- > 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. > -- 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.
