Re: [appengine-java] Re: periodic downtimes
Well, I've submitted 2 or 3 tickets to their support team last week and haven't heard back yet. Perhaps I'm doing something wrong. As far as how our app did on the app-engine: it was pretty smooth. I think the main issue we ran into was the 10 writes per entity group per second. I think that restriction may force us onto a different platform. I think we could have worked around that restriction by employing more clever memcache usage, especially now that there is CAS enabled on the memcache, but I'd be slightly nervous about updates living in memcache and getting dropped before we wrote them to the datastore. My clients pretty much decided they want to try another hosting solution, so I guess that's my only option lol. Thanks for the reply! On Sat, Feb 12, 2011 at 5:34 AM, systemsplanet wrote: > the app engine team recently fixed a problem > I was having in about 12 hrs. I couldn't add > a new application, GAE forgot I had already > authenticated my mobile phone number. > > as for your ap, I'll be interested to see > if an ap with expected high contention > will work well on gae. seems like gea is > optimized for high-reads and few > non-contending writes (like a blog). > > . > > On Feb 11, 1:37 am, bcottam wrote: >> Good point Robert, I'm not sure if it's just the datastore. My users wind >> up getting a 500 error on requests that just read data, usually even if the >> datastore has issues, you can still read from it. >> >> I'd be comfortable using memcache, but I'd want to ensure it had the same >> data integrity as the datastore (or something close anyhow). The nice thing >> about the datastore is that there is optimistic locking, so I know when >> there's contention. Currently, our users collectively modify data at about >> the same time (like 7-12 updates in a single second from several users), >> it's pretty important that I keep them in order, so I currently have my >> writes wrapped in a datastore transaction with a loop that runs about 5 >> times or until the transaction succeeds. Has anyone managed that type of >> contention in the memcache? If so, I'd love to hear some techniques that >> can ensure no update tramples a previous concurrent update. >> >> I've submitted inquiries to the billing and CPU request form, but haven't >> heard back. Does it usually take longer than 24 hours to hear back from the >> app-engine support team? >> >> Thanks > > -- > 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. > > -- 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.
Re: [appengine-java] Re: JDO @Version not working properly?
Thanks for the reply James, No, I can't do the read and the write in the same tx because I am doing a non-id based query on a different entity group in between my read and my write. But I think I've resolved the issue. It seems that when I don't do the detatch the issue is gone and the OPT_VERSION variable actually gets updated. The trick is that I needed to use the PersistenceManager for all operations. I've read that it's faster to have a dedicated "read only" PersistenceManager, so I was doing all reads through the same pm and various writes through newly created pm's. I just added a ServletContextListener, in it I setup the pm when a request comes in, and tear it down after the request is dispatched. That seems to be working like a charm. Hope this helps anyone finding themselves in the same boat. Thanks!! -bryce On Fri, Sep 3, 2010 at 6:32 AM, James wrote: > Have you tried querying and saving within the same transaction, > instead of separately? > > On Sep 2, 3:36 am, bcottam wrote: >> 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-w... >> ...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 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 google-appengine-j...@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
Re: [appengine-java] Re: new in 1.2.8: "relationship fields of type . This is not yet supported."
thanks for the info. Getting feedback like this from someone as close to the low level implementation as yourself is priceless! I think I'll be fine using either a SortedSet or a List with the @Order and the datanucleus extension on it for the Activity.ratePlans collection. This set could just be fine to order by a name, or even the Id. I know there wont be too many of these children in our clients use cases. Even in the cases where we want to allow user-specified ordering, the list shouldn't be that long. We're modeling reservations for adventure outfitters, there are only so many people you can take down a river :) I'm glad to hear you say not to optimize too eagerly, I've kinda taken the approach that I'd just make things work, and then see how I can tweak performance as needed. anyway, thanks again for all the great advice and info! -bryce On Mon, Dec 14, 2009 at 11:21 PM, Max Ross (Google) wrote: > A Set will not suffer from this same problem. The datastore has no way of > knowing what the sort function of your SortedSet might be so this will be > treated as an unordered Collection as well, but the sort will happen > in-memory as the collection is populated. If the collection has an explicit > ordering then the JDO default is probably what you want since it does all > the shifting that you'd need to implement yourself, but there is this bug > you've run into, and I suspect there are others. If you don't want the > overhead of a datastore index on displayOrder and you know you're not going > to have too many child objects, doing the sort in-memory may be fine. Don't > optimize too early though. I'd see what the performance of writes look like > with the datastore index and then go from there. > > Max > > On Mon, Dec 14, 2009 at 10:10 PM, bryce cottam wrote: >> >> do SortedSets suffer from the same problem? In particular, I could >> define a displayOrder property that was rather sparse (every 10th int >> or something: 10, 20, 30 etc.) and if I needed to insert something >> between the first and second (which shouldn't happen very often) I >> could just set it's displayOrder to 15 and throw it in the set. >> >> The only reason I bring it up, is because our app allows users to >> order certain types of data (really just one type), but frankly, they >> don't move them around much at all, it's pretty much defined at >> creation time, but *sometimes* they alter that ordering. I don't >> anticipate this being a huge problem, heck I could sort the set after >> it gets out of the datastore if I had to using a displayOrder field or >> something. I don't want to bog down my performance doing this through >> some implicit index. >> >> thanks, >> -bryce >> >> >> On Mon, Dec 14, 2009 at 11:04 PM, Max Ross (Google) >> wrote: >> > If you order by anything other than your primary key you'll take a >> > performance and cpu hit on writes but there won't be a penalty on your >> > reads. The reason the JDO default is such a problem is that it adds an >> > implicit property to each child entity containing the position of that >> > entity in its parent's list. If you ever remove or add an element in >> > this >> > list at a location that isn't the end, everything between that element >> > and >> > the end of the list needs to get shifted down. In an RDBMS you'd just >> > issue >> > an update statement to increment everything by 1 relative to its current >> > value, but the datastore doesn't support this type of relative update, >> > so >> > ends up doing one write per entity whose index needs shifting. So in >> > short, >> > don't do it this way. :-) >> > >> > Max >> > >> > On Mon, Dec 14, 2009 at 9:42 PM, bryce cottam wrote: >> >> >> >> hahaha, no that doesn't sound draconian. I remember reading that the >> >> ordering of lists can be a performance hit, I haven't bothered to look >> >> too deep into it yet (since I'm only doing a proof of concept right >> >> now). I have some questions about it though. For instance, what if I >> >> were to order by some kind of displayOrder field that I maintain? >> >> Would that also suffer a performance lag? I mainly want to move to >> >> the GAE for performance and scalability, so I think I'd appreciate a >> >> runtime/compile time warning that told me about things I was doing >> >> that would hurt my performance. >> >> >>
Re: [appengine-java] Re: new in 1.2.8: "relationship fields of type . This is not yet supported."
do SortedSets suffer from the same problem? In particular, I could define a displayOrder property that was rather sparse (every 10th int or something: 10, 20, 30 etc.) and if I needed to insert something between the first and second (which shouldn't happen very often) I could just set it's displayOrder to 15 and throw it in the set. The only reason I bring it up, is because our app allows users to order certain types of data (really just one type), but frankly, they don't move them around much at all, it's pretty much defined at creation time, but *sometimes* they alter that ordering. I don't anticipate this being a huge problem, heck I could sort the set after it gets out of the datastore if I had to using a displayOrder field or something. I don't want to bog down my performance doing this through some implicit index. thanks, -bryce On Mon, Dec 14, 2009 at 11:04 PM, Max Ross (Google) wrote: > If you order by anything other than your primary key you'll take a > performance and cpu hit on writes but there won't be a penalty on your > reads. The reason the JDO default is such a problem is that it adds an > implicit property to each child entity containing the position of that > entity in its parent's list. If you ever remove or add an element in this > list at a location that isn't the end, everything between that element and > the end of the list needs to get shifted down. In an RDBMS you'd just issue > an update statement to increment everything by 1 relative to its current > value, but the datastore doesn't support this type of relative update, so > ends up doing one write per entity whose index needs shifting. So in short, > don't do it this way. :-) > > Max > > On Mon, Dec 14, 2009 at 9:42 PM, bryce cottam wrote: >> >> hahaha, no that doesn't sound draconian. I remember reading that the >> ordering of lists can be a performance hit, I haven't bothered to look >> too deep into it yet (since I'm only doing a proof of concept right >> now). I have some questions about it though. For instance, what if I >> were to order by some kind of displayOrder field that I maintain? >> Would that also suffer a performance lag? I mainly want to move to >> the GAE for performance and scalability, so I think I'd appreciate a >> runtime/compile time warning that told me about things I was doing >> that would hurt my performance. >> >> Thanks again for helping me out so much. >> -bryce >> >> >> >> On Mon, Dec 14, 2009 at 9:06 PM, Max Ross (Google) >> wrote: >> > Ok I've got good news for you. I need to do more testing but I think >> > different parent types for child objects should work fine as long as you >> > use >> > list-ordering for your one-to-many relationships, which you really ought >> > to >> > be doing anyway. Position properties are already incredibly >> > inefficient, >> > and it turns out the bug you're running into only applies when there are >> > position properties in play. You can read more about it in this >> > section: >> > >> > http://code.google.com/appengine/docs/java/datastore/relationships.html#Owned_One_to_Many_Relationships >> > (How Ordered Collections Maintain Their Order). >> > >> > So, if you change your one-to-many relationship on RatePlan to: >> > @Persistent >> > @Order(extensions = @Extension(vendorName="datanucleus", >> > key="list-ordering", value="id")) >> > private List ratePlans = new ArrayList(); >> > >> > you should be in business. >> > >> > Position properties are so bad I'm considering turning them into a >> > meta-data >> > error that you have to explicitly silence with a jvm property. What do >> > you >> > think, too draconian? >> > >> > Max >> > >> > On Mon, Dec 14, 2009 at 11:09 AM, Max Ross (Google) >> > wrote: >> >> >> >> Sure, sorry it was such a headache for you. When I've got a fix ready >> >> I'll let you know. >> >> >> >> On Mon, Dec 14, 2009 at 10:57 AM, bryce cottam >> >> wrote: >> >>> >> >>> good point, I kinda got lost in the exceptions I was getting :) >> >>> I wound up sorting it out by making an embedded class instead of >> >>> having multiple parent classes for a given child class. Although, it >> >>> would be nice if a child class could have different parent types. >> >>> >
Re: [appengine-java] Re: new in 1.2.8: "relationship fields of type . This is not yet supported."
hahaha, no that doesn't sound draconian. I remember reading that the ordering of lists can be a performance hit, I haven't bothered to look too deep into it yet (since I'm only doing a proof of concept right now). I have some questions about it though. For instance, what if I were to order by some kind of displayOrder field that I maintain? Would that also suffer a performance lag? I mainly want to move to the GAE for performance and scalability, so I think I'd appreciate a runtime/compile time warning that told me about things I was doing that would hurt my performance. Thanks again for helping me out so much. -bryce On Mon, Dec 14, 2009 at 9:06 PM, Max Ross (Google) wrote: > Ok I've got good news for you. I need to do more testing but I think > different parent types for child objects should work fine as long as you use > list-ordering for your one-to-many relationships, which you really ought to > be doing anyway. Position properties are already incredibly inefficient, > and it turns out the bug you're running into only applies when there are > position properties in play. You can read more about it in this section: > http://code.google.com/appengine/docs/java/datastore/relationships.html#Owned_One_to_Many_Relationships > (How Ordered Collections Maintain Their Order). > > So, if you change your one-to-many relationship on RatePlan to: > @Persistent > @Order(extensions = @Extension(vendorName="datanucleus", > key="list-ordering", value="id")) > private List ratePlans = new ArrayList(); > > you should be in business. > > Position properties are so bad I'm considering turning them into a meta-data > error that you have to explicitly silence with a jvm property. What do you > think, too draconian? > > Max > > On Mon, Dec 14, 2009 at 11:09 AM, Max Ross (Google) > wrote: >> >> Sure, sorry it was such a headache for you. When I've got a fix ready >> I'll let you know. >> >> On Mon, Dec 14, 2009 at 10:57 AM, bryce cottam wrote: >>> >>> good point, I kinda got lost in the exceptions I was getting :) >>> I wound up sorting it out by making an embedded class instead of >>> having multiple parent classes for a given child class. Although, it >>> would be nice if a child class could have different parent types. >>> >>> Thanks for all your help Max. >>> -bryce >>> >>> >>> On Mon, Dec 14, 2009 at 11:30 AM, Max Ross (Google) >>> wrote: >>> > I believe the exception you're getting is the result of having multiple >>> > parents for the same type, and unfortunately that bug isn't fixed in >>> > this >>> > release. The bugs fixed in this release are: >>> > >>> > - Incorrect exception for multiple fields of same type >>> > http://code.google.com/p/datanucleus-appengine/issues/detail?id=172 >>> > >>> > - Non-persistent base classes do not work >>> > http://code.google.com/p/datanucleus-appengine/issues/detail?id=169 >>> > >>> > - Relationships in abstract base classes don't work >>> > http://code.google.com/p/datanucleus-appengine/issues/detail?id=171 >>> > >>> > >>> > On Sat, Dec 12, 2009 at 1:09 AM, bryce cottam >>> > wrote: >>> >> >>> >> hmmm I think I may have installed the patch wrong perhaps. I >>> >> still get the same error. >>> >> I'm using the same code I sent you for the test case Max. Do you see >>> >> any tell-tale signs in here that indicate I've mis-configured >>> >> something? I have datanucleus-appengine-1.0.4.1-RC2.jar on my >>> >> classpath and I removed the previous one (pretty much the same jar but >>> >> with .final.jar as it's name. I followed the steps outlined by >>> >> Jonathan. >>> >> >>> >> here is the stack trace: >>> >> java.lang.ClassCastException: oid is not instanceof >>> >> javax.jdo.identity.ObjectIdentity >>> >> at >>> >> com.resmark.model.RatePlan.jdoCopyKeyFieldsFromObjectId(RatePlan.java) >>> >> at >>> >> >>> >> org.datanucleus.store.mapped.mapping.PersistenceCapableMapping.setObjectAsValue(PersistenceCapableMapping.java:657) >>> >> at >>> >> >>> >> org.datanucleus.store.mapped.mapping.PersistenceCapableMapping.setObject(PersistenceCapableMapping.java:364) >>> >> at >>>
Re: [appengine-java] Re: new in 1.2.8: "relationship fields of type . This is not yet supported."
good point, I kinda got lost in the exceptions I was getting :) I wound up sorting it out by making an embedded class instead of having multiple parent classes for a given child class. Although, it would be nice if a child class could have different parent types. Thanks for all your help Max. -bryce On Mon, Dec 14, 2009 at 11:30 AM, Max Ross (Google) wrote: > I believe the exception you're getting is the result of having multiple > parents for the same type, and unfortunately that bug isn't fixed in this > release. The bugs fixed in this release are: > > - Incorrect exception for multiple fields of same type > http://code.google.com/p/datanucleus-appengine/issues/detail?id=172 > > - Non-persistent base classes do not work > http://code.google.com/p/datanucleus-appengine/issues/detail?id=169 > > - Relationships in abstract base classes don't work > http://code.google.com/p/datanucleus-appengine/issues/detail?id=171 > > > On Sat, Dec 12, 2009 at 1:09 AM, bryce cottam wrote: >> >> hmmm I think I may have installed the patch wrong perhaps. I >> still get the same error. >> I'm using the same code I sent you for the test case Max. Do you see >> any tell-tale signs in here that indicate I've mis-configured >> something? I have datanucleus-appengine-1.0.4.1-RC2.jar on my >> classpath and I removed the previous one (pretty much the same jar but >> with .final.jar as it's name. I followed the steps outlined by >> Jonathan. >> >> here is the stack trace: >> java.lang.ClassCastException: oid is not instanceof >> javax.jdo.identity.ObjectIdentity >> at >> com.resmark.model.RatePlan.jdoCopyKeyFieldsFromObjectId(RatePlan.java) >> at >> org.datanucleus.store.mapped.mapping.PersistenceCapableMapping.setObjectAsValue(PersistenceCapableMapping.java:657) >> at >> org.datanucleus.store.mapped.mapping.PersistenceCapableMapping.setObject(PersistenceCapableMapping.java:364) >> at >> org.datanucleus.store.appengine.DatastoreRelationFieldManager$1.setObjectViaMapping(DatastoreRelationFieldManager.java:128) >> at >> org.datanucleus.store.appengine.DatastoreRelationFieldManager$1.apply(DatastoreRelationFieldManager.java:104) >> at >> org.datanucleus.store.appengine.DatastoreRelationFieldManager.storeRelations(DatastoreRelationFieldManager.java:78) >> at >> org.datanucleus.store.appengine.DatastoreFieldManager.storeRelations(DatastoreFieldManager.java:812) >> at >> org.datanucleus.store.appengine.DatastorePersistenceHandler.insertPostProcess(DatastorePersistenceHandler.java:288) >> at >> org.datanucleus.store.appengine.DatastorePersistenceHandler.insertObjects(DatastorePersistenceHandler.java:241) >> at >> org.datanucleus.store.appengine.DatastorePersistenceHandler.insertObject(DatastorePersistenceHandler.java:225) >> at >> org.datanucleus.state.JDOStateManagerImpl.internalMakePersistent(JDOStateManagerImpl.java:3185) >> at >> org.datanucleus.state.JDOStateManagerImpl.makePersistent(JDOStateManagerImpl.java:3161) >> at >> org.datanucleus.ObjectManagerImpl.persistObjectInternal(ObjectManagerImpl.java:1298) >> at >> org.datanucleus.ObjectManagerImpl.persistObject(ObjectManagerImpl.java:1175) >> at >> org.datanucleus.jdo.JDOPersistenceManager.jdoMakePersistent(JDOPersistenceManager.java:669) >> at >> org.datanucleus.jdo.JDOPersistenceManager.makePersistent(JDOPersistenceManager.java:694) >> at com.resmark.JdoTestServlet.create(JdoTestServlet.java:183) >> at com.resmark.JdoTestServlet.doTest(JdoTestServlet.java:90) >> at com.resmark.JdoTestServlet.doGet(JdoTestServlet.java:33) >> at javax.servlet.http.HttpServlet.service(HttpServlet.java:693) >> at javax.servlet.http.HttpServlet.service(HttpServlet.java:806) >> at >> org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:487) >> at >> org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1093) >> at >> com.google.apphosting.utils.servlet.TransactionCleanupFilter.doFilter(TransactionCleanupFilter.java:43) >> at >> org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1084) >> at >> com.google.appengine.tools.development.StaticFileFilter.doFilter(StaticFileFilter.java:121) >> at >> org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1084) >> at >> org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:360) >>
Re: [appengine-java] Re: new in 1.2.8: "relationship fields of type . This is not yet supported."
hmmm I think I may have installed the patch wrong perhaps. I still get the same error. I'm using the same code I sent you for the test case Max. Do you see any tell-tale signs in here that indicate I've mis-configured something? I have datanucleus-appengine-1.0.4.1-RC2.jar on my classpath and I removed the previous one (pretty much the same jar but with .final.jar as it's name. I followed the steps outlined by Jonathan. here is the stack trace: java.lang.ClassCastException: oid is not instanceof javax.jdo.identity.ObjectIdentity at com.resmark.model.RatePlan.jdoCopyKeyFieldsFromObjectId(RatePlan.java) at org.datanucleus.store.mapped.mapping.PersistenceCapableMapping.setObjectAsValue(PersistenceCapableMapping.java:657) at org.datanucleus.store.mapped.mapping.PersistenceCapableMapping.setObject(PersistenceCapableMapping.java:364) at org.datanucleus.store.appengine.DatastoreRelationFieldManager$1.setObjectViaMapping(DatastoreRelationFieldManager.java:128) at org.datanucleus.store.appengine.DatastoreRelationFieldManager$1.apply(DatastoreRelationFieldManager.java:104) at org.datanucleus.store.appengine.DatastoreRelationFieldManager.storeRelations(DatastoreRelationFieldManager.java:78) at org.datanucleus.store.appengine.DatastoreFieldManager.storeRelations(DatastoreFieldManager.java:812) at org.datanucleus.store.appengine.DatastorePersistenceHandler.insertPostProcess(DatastorePersistenceHandler.java:288) at org.datanucleus.store.appengine.DatastorePersistenceHandler.insertObjects(DatastorePersistenceHandler.java:241) at org.datanucleus.store.appengine.DatastorePersistenceHandler.insertObject(DatastorePersistenceHandler.java:225) at org.datanucleus.state.JDOStateManagerImpl.internalMakePersistent(JDOStateManagerImpl.java:3185) at org.datanucleus.state.JDOStateManagerImpl.makePersistent(JDOStateManagerImpl.java:3161) at org.datanucleus.ObjectManagerImpl.persistObjectInternal(ObjectManagerImpl.java:1298) at org.datanucleus.ObjectManagerImpl.persistObject(ObjectManagerImpl.java:1175) at org.datanucleus.jdo.JDOPersistenceManager.jdoMakePersistent(JDOPersistenceManager.java:669) at org.datanucleus.jdo.JDOPersistenceManager.makePersistent(JDOPersistenceManager.java:694) at com.resmark.JdoTestServlet.create(JdoTestServlet.java:183) at com.resmark.JdoTestServlet.doTest(JdoTestServlet.java:90) at com.resmark.JdoTestServlet.doGet(JdoTestServlet.java:33) at javax.servlet.http.HttpServlet.service(HttpServlet.java:693) at javax.servlet.http.HttpServlet.service(HttpServlet.java:806) at org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:487) at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1093) at com.google.apphosting.utils.servlet.TransactionCleanupFilter.doFilter(TransactionCleanupFilter.java:43) at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1084) at com.google.appengine.tools.development.StaticFileFilter.doFilter(StaticFileFilter.java:121) at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1084) at org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:360) at org.mortbay.jetty.security.SecurityHandler.handle(SecurityHandler.java:216) at org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:181) at org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:712) at org.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java:405) at com.google.apphosting.utils.jetty.DevAppEngineWebAppContext.handle(DevAppEngineWebAppContext.java:70) at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:139) at com.google.appengine.tools.development.JettyContainerService$ApiProxyHandler.handle(JettyContainerService.java:352) at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:139) at org.mortbay.jetty.Server.handle(Server.java:313) at org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:506) at org.mortbay.jetty.HttpConnection$RequestHandler.headerComplete(HttpConnection.java:830) at org.mortbay.jetty.HttpParser.parseNext(HttpParser.java:514) at org.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java:211) at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:381) at org.mortbay.io.nio.SelectChannelEndPoint.run(SelectChannelEndPoint.java:396) at org.mortbay.thread.BoundedThreadPool$PoolThread.run(BoundedThreadPool.java:442) I've got to be missing something. :( thanks, -bryce On Fri, Dec 11, 2009 at 8:54 AM, bryce cottam wrote: > Thanks a million Max, I've been on the road for a few days but I
Re: [appengine-java] Re: new in 1.2.8: "relationship fields of type . This is not yet supported."
Thanks a million Max, I've been on the road for a few days but I'm looking forward to trying this out when I get back. Thanks for the link Jonathan. -bryce On Dec 11, 2009 6:50 AM, "Jonathan 'J5' Cook" < jonathan.j5.c...@gmail.com> wrote: Thanks for the fix, Max and perfect timing for me :) I just upgraded to 1.2.8 and started having this issue last night. For those who don't/didn't already know (like myself), here is a link to instructions Max wrote on how to install a new plugin version into the SDK: http://code.google.com/p/datanucleus-appengine/wiki/HowToUpdateTheSDKWithANewPluginVersion Regards, J5 On Dec 10, 11:59 am, "Max Ross (Google)" > wrote: > I've posted a bug fix release candidate containing this fix here: http://datanucleus-appengine.googlecode.com/files/appengine-orm-1.0.4... > > On Tue, Dec 8, 2009 at 5:26 PM, bryce cottam wrote: > > That's great news Ma... > > On Dec 8, 2009 5:20 PM, "Max Ross (Google)" > > >> > > wrote: > > > I've filed bug > > http://code.google.com/p/datanucleus-appengine/issues/detail?id=1... > > On Tue, Dec 8, 2009 at 11:29 AM, bryce cottam wrote: > > >> > > It's all goo... > > google-appengine-java+unsubscr...@googlegroups.com > > > . > > For more options, visit this group at > > http://groups.google.com/group/google-appengine-j... -- 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-j...@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.
Re: [appengine-java] Re: oid is not instanceof javax.jdo.identity.ObjectIdentity
On the ActivityReservation model object, there is an instance of RatePlan (which is also a child object of Activity). So, here's a thought, I will try it out later, but I thought I'd ask right now about it: how about having subclasses of RatePlan that live on different parent objects? since RatePlan does not have a pointer up to it's parent, I think this could work, but I don't know about the underlying app-engine JDO implementation issues that might cause. I'm thinking something like ActivityRatePlan, BundledRatePlan etc. that don't really add any api/field functionality, but do make it so that only a Bundle is the parent of a BundledRatePlan, and only Activity is the parent of ActivityRatePlan etc. etc. do you think that would cause any issues? I'd love it if you could look into allowing more than one parent object type for a given child object type. If it's not too much trouble, it'd really help me out. in your Person example above, the loadAddress() method probably uses either a PersistenceManager or some generic wrapper for it? If that's the case, I'm wondering how that scales. I've kind of viewed one of the main advantages of using JDO/JPA is that the persistence framework deals with that lazy loading/orphan deletion for you. I could also make some kind of embedded field that is embedded only, I think I've had luck with putting those kinds of objects on multiple parent object without an issue. That may work for me. thanks again Max, you've been a big help. -bryce On Wed, Dec 9, 2009 at 11:49 AM, Max Ross (Google) wrote: > I don't see a class that is owned by more than one entity in your latest > example. What exactly should I be looking at? > > Your understanding of the BigTable layout is correct, but you're bumping > into a limitation of how we've mapped JDO on to that layout. The low-level > api knows nothing about your data model and will allow you to create > whatever parent/child relationships you want. However, the low-level api > also knows nothing about ownership and dependent data. We need JDO to > enforce these expectations, and in order to enforce these expectations > transactionally we need to put owned entities in the same entity group as > their parents. We also assume that each child object only has one type of > parent, and that restriction is causing problems for you. > > Why do we have that last restriction? To be honest, I never considered not > having it because in a relational database, if you're modeling ownership > with foreign keys, the foreign key that points to your "owner" typically > points to a record in a specific table - the schema dictates the type of the > parent. With JDO on top of the datastore, however, it does seem like we can > take advantage of the underlying flexibility. So long as the relationship > isn't bidirectional (no parent pointer on the child), you should be able to > have an object be the child of any number of different parents. Very > interesting, thanks for pushing! I'll file an issue for this. It might be > easy or it might be hard, I'm not sure. > > So what can you do right now? Unfortunately you're stuck with unowned > relationships. Note, however, that just because you've implemented > something as an unowned relationship doesn't mean you need to expose it that > way in your object model. The datastore doesn't do joins, so something like > this: > > class Person { > > Key addressKey; > transient Address address; > > synchronized Address getAddress() { > if (address == null) { > address = loadAddress(); > } > return address; > } > > is not actually any less efficient than using an owned relationship. Yes, > you have to write more code and it's up to you to ensure that the Address > gets deleted when the Person gets deleted, but in terms of the code you need > to write to interact with the model objects it shouldn't be that different. > > Hope this helps, > Max > On Tue, Dec 8, 2009 at 11:15 PM, bryce cottam wrote: >> >> Thanks for filing that Max. >> >> I'm kind of interested in your findings because there is another place >> where I'm doing about the same thing (i.e. making a RatePlan instance >> a direct child of an Entity other than Activity) and it works fine in >> that case most of the time. Sometimes it gives me the "oid is not an >> instance of javax.jdo.identity.ObjectIdentity" exception. >> >> here's the model: >> @PersistenceCapable(identityType=IdentityType.APPLICATION) >> public class ActivityReservation extends BaseBean >> { >> �...@primarykey >
Re: [appengine-java] Re: oid is not instanceof javax.jdo.identity.ObjectIdentity
>> public class Activity { >> @PrimaryKey >> @Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY) >> private Key id; >> >> @Persistent >> private List ratePlans = new ArrayList(); >> } >> >> @PersistenceCapable(identityType = IdentityType.APPLICATION) >> public class Bundle { >> @PrimaryKey >> @Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY) >> private Key id; >> >> @Persistent >> private RatePlan ratePlan; >> >> public void setRatePlan(RatePlan ratePlan) { >> this.ratePlan = ratePlan; >> } >> } >> >> And here's the unit test I turned your code into that generates the >> exception: >> public void testBryce() { >> pm.newQuery(Activity.class).execute(); >> >> Bundle bundle = new Bundle(); >> bundle.setRatePlan(new RatePlan()); >> >> pm.makePersistent(bundle); >> } >> >> I believe the issue is that RatePlan is owned by two different objects in >> your model - Bundle and Activity. Due to the nature of primary keys in the >> app engine datastore, a class can only have a single owner. We detect other >> flavors of this scenario when the entity meta-data is loaded but not this >> particular variant. I'll file a bug and try to produce a useful exception. >> To work around this you'll need to either switch Activity.ratePlans or >> Bundle.ratePlans to be an unowned relationship and just store the Key of the >> RatePlan rather than the RatePlan itself. Please give that a try and let me >> know how it goes. >> >> Thanks, >> Max >> On Tue, Dec 8, 2009 at 10:19 AM, bryce cottam wrote: >>> >>> No worries Max, I'm using 1.2.6 right now, so the "multiple instance" bug >>> isn't an issue right now. Whenever you get to it is fine. As always I >>> appreciate your input. >>> >>> Thanks >>> -bryce >>> >>> On Dec 8, 2009 10:14 AM, "Max Ross (Google)" >>> wrote: >>> >>> Hi Bryce, >>> >>> I started digging into you issue and quickly bumped into the "Multiple >>> relationships of the same type" bug for which I posted the workaround. Then >>> I got bogged down with unrelated stuff. I have definite plans to get back >>> to your example today. Thanks for being patient, and sorry this is taking >>> so long. >>> >>> Max >>> >>> On Mon, Dec 7, 2009 at 11:35 PM, bcottam wrote: > > >>> Max, have you had a chance... >>> >>> -- >>> >>> 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-j...@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. >> > > -- > > 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-j...@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. > -- 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-j...@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.
Re: [appengine-java] Re: new in 1.2.8: "relationship fields of type . This is not yet supported."
That's great news Max! Thanks so much for looking into this and getting a solution in the works so fast. Thanks, -bryce On Dec 8, 2009 5:20 PM, "Max Ross (Google)" > wrote: I've filed bug http://code.google.com/p/datanucleus-appengine/issues/detail?id=169 to track the problem with non-persistent base classes. I have a fix in the works. I'll be posting a release candidate with this fix and hopefully a few others in the next day or two. Thanks, Max On Tue, Dec 8, 2009 at 11:29 AM, bryce cottam wrote: > > > It's all good, we're just trying to get to the bottom of the issue. I'm > sure the use of the word... > > -- > > > > You received this message because you are subscribed to the Google > Groups "Google App Engine fo... > -- You received this message because you are subscribed to the Google Groups "Google App Engine f... -- 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-j...@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.
Re: [appengine-java] Re: new in 1.2.8: "relationship fields of type . This is not yet supported."
It's all good, we're just trying to get to the bottom of the issue. I'm sure the use of the word "enhancer" was just contextual. You have indeed demonstrated that datanucleus isn't complaining. We're all friends here :) thanks for helping us narrow the the root cause of the problem down. Thanks, -bryce On Dec 8, 2009 11:18 AM, "datanucleus" wrote: > 1) why the enhancer complains that BaseObject need to be enhanced even > though it does not declar... There is no problem presented here with the "enhancer" complaining. All is at runtime actually, thrown from a call by GAE/J's DN plugin, as shown by the stack trace above. As I've already stated, DataNucleus does NOT require any base class to be persistent when the classes are declared as I've already shown. If you have some other situation then demonstrate it -- You received this message because you are subscribed to the Google Groups "Google App Engine fo... -- 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-j...@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.
Re: [appengine-java] Re: oid is not instanceof javax.jdo.identity.ObjectIdentity
No worries Max, I'm using 1.2.6 right now, so the "multiple instance" bug isn't an issue right now. Whenever you get to it is fine. As always I appreciate your input. Thanks -bryce On Dec 8, 2009 10:14 AM, "Max Ross (Google)" > wrote: Hi Bryce, I started digging into you issue and quickly bumped into the "Multiple relationships of the same type" bug for which I posted the workaround. Then I got bogged down with unrelated stuff. I have definite plans to get back to your example today. Thanks for being patient, and sorry this is taking so long. Max On Mon, Dec 7, 2009 at 11:35 PM, bcottam wrote: > > Max, have you had a chance... -- 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-j...@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.
Re: [appengine-java] Re: new in 1.2.8: "relationship fields of type . This is not yet supported."
Thanks for the link Max. Having BaseBean be PersistenceCapable isn't really a requirement. It'd be nice, 'cause pretty much every bean in my class structure is going to have an id field, a getter/setter and the exact same JDO annotation metadata on that field. It'd be nice to just have that defined once in a base class. However, it's no big thing to just implement an id field on every class, so I can certainly do without BaseBean being persistable. However, I'm noticing above mentioned errors when I make BaseBean a plain-ol class with no persistence metadata (i.e. it just implements equals and hashCode) and the appengine datanucleus plugin seems to be telling me that BaseBean needs to be enhanced. So, either way I go, I'm running into issues. I'd like to try to get to the bottom of why my non-persistable base class is being required to have been enhanced. Perhaps something is wrong with my configuration/meta data? perhaps a bug? any feedback/suggestions would be great. thanks! -bryce On Mon, Dec 7, 2009 at 12:04 PM, Max Ross (Google) wrote: > I need to investigate the requirement that BaseBean be PersistenceCapable, > but the relationship exception you're getting is most likely the result of a > separate bug. Here's a thread with the workaround: > https://groups.google.com/group/google-appengine-java/browse_thread/thread/241f366dde05f9f3# > > Max > > On Mon, Dec 7, 2009 at 1:41 AM, bryce cottam wrote: >> >> right, we're certainly on the same page on what should/shouldn't be >> persisted. I have that override on every single class that subclasses >> BaseBean. I would never expect JDO/datanucleus or any other framework >> for that matter to "magically" persist a field in a non-peristable >> super class. That's why I override it in every subclass. Again, I >> had it in there as a place holder until GAE supported persisting super >> class fields in subclasses. in the release notes of 1.2.8 of GAE, it >> indicates such functionality is available, so I removed my overrides, >> made BaseBean persistable and started testing. Once I saw the error >> in my original message, I reverted everything back to a state where >> BaseBean is not persistable, and in fact, it is abstract and I removed >> the implementation of the "id" field and property getter/setters and >> migrated that all down to each subclassing bean. So, given my code >> above, no one should be requiring BaseBean to be persistable or even >> enhanced. Good tip on the point that a plugin may be causing this, >> here is the stack trace I posted earlier: >> >> Persistent class "Class com.resmark.client.model.BaseBean does not >> seem to have been enhanced. You may want to rerun the enhancer and >> check for errors in the output." has no table in the database, but the >> operation requires it. Please check the specification of the MetaData >> for this class. >> at >> org.datanucleus.jdo.NucleusJDOHelper.getJDOExceptionForNucleusException(NucleusJDOHelper.java:375) >> at >> org.datanucleus.jdo.JDOPersistenceManager.jdoMakePersistent(JDOPersistenceManager.java:674) >> at >> org.datanucleus.jdo.JDOPersistenceManager.makePersistent(JDOPersistenceManager.java:694) >> at >> com.resmark.server.model.service.BaseDataService.create(BaseDataService.java:227) >> at >> com.resmark.server.SetupServiceImpl.updateOrCreate(SetupServiceImpl.java:123) >> at >> com.resmark.server.SetupServiceImpl.updateOrCreateActivity(SetupServiceImpl.java:60) >> at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) >> at >> sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) >> at >> sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) >> at java.lang.reflect.Method.invoke(Method.java:597) >> at >> com.google.appengine.tools.development.agent.runtime.Runtime.invoke(Runtime.java:100) >> at >> com.google.gwt.user.server.rpc.RPC.invokeAndEncodeResponse(RPC.java:527) >> at >> com.google.gwt.user.server.rpc.RemoteServiceServlet.processCall(RemoteServiceServlet.java:166) >> at >> com.google.gwt.user.server.rpc.RemoteServiceServlet.doPost(RemoteServiceServlet.java:86) >> at javax.servlet.http.HttpServlet.service(HttpServlet.java:713) >> at javax.servlet.http.HttpServlet.service(HttpServlet.java:806) >> at >> org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:487) >> at >> org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(Servlet
Re: [appengine-java] Re: new in 1.2.8: "relationship fields of type . This is not yet supported."
right, we're certainly on the same page on what should/shouldn't be persisted. I have that override on every single class that subclasses BaseBean. I would never expect JDO/datanucleus or any other framework for that matter to "magically" persist a field in a non-peristable super class. That's why I override it in every subclass. Again, I had it in there as a place holder until GAE supported persisting super class fields in subclasses. in the release notes of 1.2.8 of GAE, it indicates such functionality is available, so I removed my overrides, made BaseBean persistable and started testing. Once I saw the error in my original message, I reverted everything back to a state where BaseBean is not persistable, and in fact, it is abstract and I removed the implementation of the "id" field and property getter/setters and migrated that all down to each subclassing bean. So, given my code above, no one should be requiring BaseBean to be persistable or even enhanced. Good tip on the point that a plugin may be causing this, here is the stack trace I posted earlier: Persistent class "Class com.resmark.client.model.BaseBean does not seem to have been enhanced. You may want to rerun the enhancer and check for errors in the output." has no table in the database, but the operation requires it. Please check the specification of the MetaData for this class. at org.datanucleus.jdo.NucleusJDOHelper.getJDOExceptionForNucleusException(NucleusJDOHelper.java:375) at org.datanucleus.jdo.JDOPersistenceManager.jdoMakePersistent(JDOPersistenceManager.java:674) at org.datanucleus.jdo.JDOPersistenceManager.makePersistent(JDOPersistenceManager.java:694) at com.resmark.server.model.service.BaseDataService.create(BaseDataService.java:227) at com.resmark.server.SetupServiceImpl.updateOrCreate(SetupServiceImpl.java:123) at com.resmark.server.SetupServiceImpl.updateOrCreateActivity(SetupServiceImpl.java:60) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:597) at com.google.appengine.tools.development.agent.runtime.Runtime.invoke(Runtime.java:100) at com.google.gwt.user.server.rpc.RPC.invokeAndEncodeResponse(RPC.java:527) at com.google.gwt.user.server.rpc.RemoteServiceServlet.processCall(RemoteServiceServlet.java:166) at com.google.gwt.user.server.rpc.RemoteServiceServlet.doPost(RemoteServiceServlet.java:86) at javax.servlet.http.HttpServlet.service(HttpServlet.java:713) at javax.servlet.http.HttpServlet.service(HttpServlet.java:806) at org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:487) at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1093) at com.google.apphosting.utils.servlet.TransactionCleanupFilter.doFilter(TransactionCleanupFilter.java:43) at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1084) at com.google.appengine.tools.development.StaticFileFilter.doFilter(StaticFileFilter.java:121) at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1084) at org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:360) at org.mortbay.jetty.security.SecurityHandler.handle(SecurityHandler.java:216) at org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:181) at org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:712) at org.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java:405) at com.google.apphosting.utils.jetty.DevAppEngineWebAppContext.handle(DevAppEngineWebAppContext.java:70) at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:139) at com.google.appengine.tools.development.JettyContainerService$ApiProxyHandler.handle(JettyContainerService.java:352) at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:139) at org.mortbay.jetty.Server.handle(Server.java:313) at org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:506) at org.mortbay.jetty.HttpConnection$RequestHandler.content(HttpConnection.java:844) at org.mortbay.jetty.HttpParser.parseNext(HttpParser.java:644) at org.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java:211) at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:381) at org.mortbay.io.nio.SelectChannelEndPoint.run(SelectChannelEndPoint.java:396) at org.mortbay.thread.BoundedThreadPool$PoolThread.run(BoundedThreadPool.java:442) and I guess I glanced over it before, but here's the nested stack trace: Persistent class "Class com.resmark.client.model.BaseBean doe
Re: [appengine-java] Re: new in 1.2.8: "relationship fields of type . This is not yet supported."
Object thatId = that.getId(); if (thisId != null && thatId != null) { equal = thisId.equals(thatId); } } return equal; } @Override public int hashCode() { if (hash == null) { hash = getId() == null ? super.hashCode() : getClass().getName().hashCode() ^ getId().hashCode(); } return hash; } } @PersistenceCapable(identityType=IdentityType.APPLICATION) public class Activity extends BaseBean implements NamedBean { @Persistent private Key id; @Persistent private String name; @Persistent private Text description; @Persistent private PricingModel pricingModel = PricingModel.PER_GUEST; @Persistent private List ratePlans = new ArrayList(); } any thoughts? Seems to me that JDO/datanucleus shouldn't even care about BaseBean at this poiint. There's simply nothing in it. It implements an interface that has getId() as a method, but the class it's self is abstract, so I'm not sure what to think here. If the spec says that you can have a base class that has methods/fields overriden by persistence capable subclasses, then this looks like a bug to me. thanks, -bryce On Mon, Dec 7, 2009 at 1:39 AM, bryce cottam wrote: > well, I should clarify: > BaseBean used to just hold the field id: > > private Key id; > > public Key getId() > { > return id; > } > public void setId(Key id) > { > this.id = id; > } > > > and subclasses would override this method and put the appropriate JDO > annotations in. I was doing this because inheritance of this type > wasn't supported when I stared writing my app: > > public class SomeSubClass extends BaseBean > { > @Override > @PrimaryKey > @Persistent(valueStrategy=IdGeneratorStrategy.IDENTITY) > public Key getId() > { > return super.getId(); > } > public void setId(Key id) > { > super.setKey(id); > } > ... > } > > now, again, I was only doing this as a fill-gap because I knew that > subclassing and persisting a super class's fields would be supported > in a future release of the sdk. > so, when I first updated to 1.2.8, I didn't change anything about any > class. i.e. BaseBean was still a simple POJO with no annotations, and > simply had a field/property in common > with it's persistable sub-classes. I'm not sure why JDO would feel > the need to have BaseBean persisted in this case, given that the only > fields on that class are clearly overriden in it's subclasses. > > However, that aside, it still seems like a problem if you have 2 > relationships, one of type one-to-one and another of type one-to-many > that are completely different (both at compile time and at runtime) > that *happen* to share a common ancestor (which is never persisted) > and your persistence wrapper thinks they are realationships of the > same data type. > > not sure if I'm making that clear, sorry I left out that detail in the > first place, but my main point is independent of it: the relationships > are different, with different comple and runtime types. They > shouldn't ever be considered the same type. I mean, everythings an > Object but you don't get this error when that happens. > > > > On Mon, Dec 7, 2009 at 1:28 AM, datanucleus wrote: >>> It also is the central place for entities "id" field: >> >> DataNucleus, the project (as opposed to the Google plugin), only >> "insists" that something is enhanced if you are using its fields/ >> properties as persistent. If this class has an "id" field and you >> expect that field to be persisted then ***JDO*** (or JPA for that >> matter too) requires that this class is persistable. If instead you >> have a field "id" in that class yet you define a (persistent) property >> (getId()/setId()) in the persistable subclasses as then that >> superclass doesn't have to be persistable ... i.e as per the JDO/JPA >> specs >> >> -- >> >> 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-j...@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. >> >> >> > -- 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-j...@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.
Re: [appengine-java] Re: new in 1.2.8: "relationship fields of type . This is not yet supported."
well, I should clarify: BaseBean used to just hold the field id: private Key id; public Key getId() { return id; } public void setId(Key id) { this.id = id; } and subclasses would override this method and put the appropriate JDO annotations in. I was doing this because inheritance of this type wasn't supported when I stared writing my app: public class SomeSubClass extends BaseBean { @Override @PrimaryKey @Persistent(valueStrategy=IdGeneratorStrategy.IDENTITY) public Key getId() { return super.getId(); } public void setId(Key id) { super.setKey(id); } ... } now, again, I was only doing this as a fill-gap because I knew that subclassing and persisting a super class's fields would be supported in a future release of the sdk. so, when I first updated to 1.2.8, I didn't change anything about any class. i.e. BaseBean was still a simple POJO with no annotations, and simply had a field/property in common with it's persistable sub-classes. I'm not sure why JDO would feel the need to have BaseBean persisted in this case, given that the only fields on that class are clearly overriden in it's subclasses. However, that aside, it still seems like a problem if you have 2 relationships, one of type one-to-one and another of type one-to-many that are completely different (both at compile time and at runtime) that *happen* to share a common ancestor (which is never persisted) and your persistence wrapper thinks they are realationships of the same data type. not sure if I'm making that clear, sorry I left out that detail in the first place, but my main point is independent of it: the relationships are different, with different comple and runtime types. They shouldn't ever be considered the same type. I mean, everythings an Object but you don't get this error when that happens. On Mon, Dec 7, 2009 at 1:28 AM, datanucleus wrote: >> It also is the central place for entities "id" field: > > DataNucleus, the project (as opposed to the Google plugin), only > "insists" that something is enhanced if you are using its fields/ > properties as persistent. If this class has an "id" field and you > expect that field to be persisted then ***JDO*** (or JPA for that > matter too) requires that this class is persistable. If instead you > have a field "id" in that class yet you define a (persistent) property > (getId()/setId()) in the persistable subclasses as then that > superclass doesn't have to be persistable ... i.e as per the JDO/JPA > specs > > -- > > 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-j...@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. > > > -- 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-j...@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.
Re: [appengine-java] Re: oid is not instanceof javax.jdo.identity.ObjectIdentity
Okay, sorry for the delay, I haven't been able to focus on this for a few days. here is the full (including the jar libararies in case there is an issue with them). http://www.resmarksystems.com/code/JdoTest.zip It's a very simple Servlet, by hitting the url hostname/jdotest you should execute the test case that is failing for me. I really appreciate your taking a look at this. I'm looking forward to getting it working. -bryce On Tue, Dec 1, 2009 at 10:15 PM, Max Ross (Google) wrote: > Just give me the smallest amount of compilable, runnable code that > demonstrates the incorrect behavior. A unit test is preferable because I > can just drop it into my own test framework and run it, but I'll take > whatever format you can manage. > > Thanks, > Max > > On Tue, Dec 1, 2009 at 1:18 PM, bryce cottam wrote: >> >> yeah, I didn't see a TransactionNotActiveException. >> here is my jdoconfig.xml: >> >> > >> value="org.datanucleus.store.appengine.jdo.DatastoreJDOPersistenceManagerFactory"/> >> >> > value="true"/> >> > value="true"/> >> >> > value="true"/> >> >> >> I think the only thing I changed was putting in this line: >> > value="true"/> >> >> which may explain why I don't get the TransactionNotActiveException. >> So, for this unit test/servlet, you want me to just post the class >> file here, or strip down all my code and put up all my model classes >> and the test case/servlet code somewhere in a war or something? >> >> h I just commented out that line, and I still get the same >> behavior (i.e. I don't get the TransactionNotActiveException). Not >> sure what's going on. >> >> thanks, >> -bryce >> >> On Tue, Dec 1, 2009 at 2:04 PM, Max Ross (Google) >> wrote: >> > Now I'm starting to suspect something funny going on with your config. >> > I >> > received a TransactionNotActiveException when I tried to run your code >> > without starting the txn, and the fact that you didn't receive that >> > exception doesn't make any sense to me. I can't explain why you see the >> > exception and I don't. The best thing would be for you to put together >> > a >> > stripped down test case that demonstrates the problem. An actual unit >> > test >> > would be ideal, but if you're not a position to write one then just a >> > simple >> > standalone servlet should suffice. >> > >> > Thanks, >> > Max >> > >> > >> > On Tue, Dec 1, 2009 at 1:00 PM, bryce cottam wrote: >> >> >> >> that is both a type-o and it was missing :) It was missing from my >> >> test code, but it was present in my "real" code. So, after putting >> >> the tx.begin() in the test code, I get the exact same behavior as the >> >> "real" code (i.e. nothing gets written to the datastore and I get the >> >> exception. Sorry about missing that in the code I posted. >> >> >> >> I'm kinda lost on where to go with this and where to look. I did >> >> notice that the code actually prompts the exception is in the >> >> datanucleus core and there is a comment above it that says: >> >> / TODO Factor out this PersistenceCapable reference >> >> ((PersistenceCapable)value).jdoCopyKeyFieldsFromObjectId(new >> >> AppIDObjectIdFieldConsumer(param, om, ps, >> >> javaTypeMappings), id); >> >> >> >> so, I'm not sure if this has soemthing to do with code style >> >> datanucleus is trying to phase out or what? Again, I'm not gonna be >> >> shocked if I'm missing something though. >> >> thanks! >> >> -bryce >> >> >> >> >> >> On Tue, Dec 1, 2009 at 1:53 PM, Max Ross (Google) >> >> wrote: >> >> > I don't see a call to tx.begin() in the code below. Is that a typo >> >> > or >> >> > is it >> >> > actually missing? >> >> > >> >> > On Tue, Dec 1, 2009 at 12:29 PM, bryce cottam >> >> > wrote: >> >> >> >> >> >> thanks so much for checking into this Max. >> >> >> >> >> >> The data that I'm saving is user generated, so there's not a set >> >> >> script for it. Co
Re: [appengine-java] Re: oid is not instanceof javax.jdo.identity.ObjectIdentity
yeah, I didn't see a TransactionNotActiveException. here is my jdoconfig.xml: I think the only thing I changed was putting in this line: which may explain why I don't get the TransactionNotActiveException. So, for this unit test/servlet, you want me to just post the class file here, or strip down all my code and put up all my model classes and the test case/servlet code somewhere in a war or something? h I just commented out that line, and I still get the same behavior (i.e. I don't get the TransactionNotActiveException). Not sure what's going on. thanks, -bryce On Tue, Dec 1, 2009 at 2:04 PM, Max Ross (Google) wrote: > Now I'm starting to suspect something funny going on with your config. I > received a TransactionNotActiveException when I tried to run your code > without starting the txn, and the fact that you didn't receive that > exception doesn't make any sense to me. I can't explain why you see the > exception and I don't. The best thing would be for you to put together a > stripped down test case that demonstrates the problem. An actual unit test > would be ideal, but if you're not a position to write one then just a simple > standalone servlet should suffice. > > Thanks, > Max > > > On Tue, Dec 1, 2009 at 1:00 PM, bryce cottam wrote: >> >> that is both a type-o and it was missing :) It was missing from my >> test code, but it was present in my "real" code. So, after putting >> the tx.begin() in the test code, I get the exact same behavior as the >> "real" code (i.e. nothing gets written to the datastore and I get the >> exception. Sorry about missing that in the code I posted. >> >> I'm kinda lost on where to go with this and where to look. I did >> notice that the code actually prompts the exception is in the >> datanucleus core and there is a comment above it that says: >> / TODO Factor out this PersistenceCapable reference >> ((PersistenceCapable)value).jdoCopyKeyFieldsFromObjectId(new >> AppIDObjectIdFieldConsumer(param, om, ps, >> javaTypeMappings), id); >> >> so, I'm not sure if this has soemthing to do with code style >> datanucleus is trying to phase out or what? Again, I'm not gonna be >> shocked if I'm missing something though. >> thanks! >> -bryce >> >> >> On Tue, Dec 1, 2009 at 1:53 PM, Max Ross (Google) >> wrote: >> > I don't see a call to tx.begin() in the code below. Is that a typo or >> > is it >> > actually missing? >> > >> > On Tue, Dec 1, 2009 at 12:29 PM, bryce cottam wrote: >> >> >> >> thanks so much for checking into this Max. >> >> >> >> The data that I'm saving is user generated, so there's not a set >> >> script for it. Conceptually what I'm doing is this: >> >> >> >> Bundle bundle = new Bundle(); >> >> >> >> bundle.setName("My Bundle"); >> >> bundle.setDescription(new >> >> com.google.appengine.api.datastore.Text("My Description")); >> >> bundle.setPricingModel(PricingModel.PER_GUEST); >> >> >> >> RatePlan ratePlan = new RatePlan(); >> >> ratePlan.setPricingModel(PricingModel.PER_GUEST); >> >> ratePlan.setAdultPrice(new >> >> java.math.BigDecimal("300.00")); >> >> ratePlan.setYouthPrice(new >> >> java.math.BigDecimal("275.00")); >> >> >> >> bundle.setRatePlan(ratePlan); >> >> >> >> List activityIds = getActivityIds(); >> >> int i = 0; >> >> for (Key id : activityIds) { >> >> BundledActivity bundledActivity = new >> >> BundledActivity(); >> >> bundledActivity.setDay(++i); >> >> >> >> ActivityFK activityFk = new ActivityFK(); >> >> activityFk.setKey(id); >> >> activityFk.setName("activity " + i); >> >> >> >> activityFk.setPricingModel(PricingModel.PER_GUEST); >> >> >> >> bundledActivity.setActivity(activityFk); >> >> >> >> RatePlan activityRate = new RatePlan(); >> >> &g
Re: [appengine-java] Re: oid is not instanceof javax.jdo.identity.ObjectIdentity
that is both a type-o and it was missing :) It was missing from my test code, but it was present in my "real" code. So, after putting the tx.begin() in the test code, I get the exact same behavior as the "real" code (i.e. nothing gets written to the datastore and I get the exception. Sorry about missing that in the code I posted. I'm kinda lost on where to go with this and where to look. I did notice that the code actually prompts the exception is in the datanucleus core and there is a comment above it that says: / TODO Factor out this PersistenceCapable reference ((PersistenceCapable)value).jdoCopyKeyFieldsFromObjectId(new AppIDObjectIdFieldConsumer(param, om, ps, javaTypeMappings), id); so, I'm not sure if this has soemthing to do with code style datanucleus is trying to phase out or what? Again, I'm not gonna be shocked if I'm missing something though. thanks! -bryce On Tue, Dec 1, 2009 at 1:53 PM, Max Ross (Google) wrote: > I don't see a call to tx.begin() in the code below. Is that a typo or is it > actually missing? > > On Tue, Dec 1, 2009 at 12:29 PM, bryce cottam wrote: >> >> thanks so much for checking into this Max. >> >> The data that I'm saving is user generated, so there's not a set >> script for it. Conceptually what I'm doing is this: >> >> Bundle bundle = new Bundle(); >> >> bundle.setName("My Bundle"); >> bundle.setDescription(new >> com.google.appengine.api.datastore.Text("My Description")); >> bundle.setPricingModel(PricingModel.PER_GUEST); >> >> RatePlan ratePlan = new RatePlan(); >> ratePlan.setPricingModel(PricingModel.PER_GUEST); >> ratePlan.setAdultPrice(new java.math.BigDecimal("300.00")); >> ratePlan.setYouthPrice(new java.math.BigDecimal("275.00")); >> >> bundle.setRatePlan(ratePlan); >> >> List activityIds = getActivityIds(); >> int i = 0; >> for (Key id : activityIds) { >> BundledActivity bundledActivity = new >> BundledActivity(); >> bundledActivity.setDay(++i); >> >> ActivityFK activityFk = new ActivityFK(); >> activityFk.setKey(id); >> activityFk.setName("activity " + i); >> activityFk.setPricingModel(PricingModel.PER_GUEST); >> >> bundledActivity.setActivity(activityFk); >> >> RatePlan activityRate = new RatePlan(); >> >> activityRate.setPricingModel(PricingModel.PER_GUEST); >> activityRate.setAdultPrice(new >> java.math.BigDecimal("150.00")); >> activityRate.setYouthPrice(new >> java.math.BigDecimal("120.00")); >> >> bundledActivity.setRatePlan(activityRate); >> bundle.getActivities().add(bundledActivity); >> } >> >> PersistenceManager pm = PMF.createManager(); >> Transaction tx = pm.currentTransaction(); >> >> try { >> bundle = pm.makePersistent(bundle); >> tx.commit(); >> } >> finally { >> if (tx.isActive()) { >> tx.rollback(); >> } >> >> pm.close(); >> } >> >> I get the Bundle saved just fine, but when it tries to save it's child >> BundledActivity instances, it breaks. However, when I do the same >> thing through the UI of my app, I get the error when attempting to >> save the Bundle (i.e. nothing gets written to the datastore, where as >> in this test code above, the parent Bundle is getting written, but >> none of it's children are getting written). >> >> Of course anytime I post my code, I kind of summarize, there are >> utilities that I use etc. But I am able to reproduce the issue >> without using any of my "helper" apis. I am completely open to just >> sending you my code (it's all proof of concept right now, so no >> disclosure issues) and you can see how all the pieces I'm using are >> fitting together. >> >> I appreciate you taking a look at this, I'd love to know if I'm doing >> something wrong. >> than
Re: [appengine-java] Re: oid is not instanceof javax.jdo.identity.ObjectIdentity
thanks so much for checking into this Max. The data that I'm saving is user generated, so there's not a set script for it. Conceptually what I'm doing is this: Bundle bundle = new Bundle(); bundle.setName("My Bundle"); bundle.setDescription(new com.google.appengine.api.datastore.Text("My Description")); bundle.setPricingModel(PricingModel.PER_GUEST); RatePlan ratePlan = new RatePlan(); ratePlan.setPricingModel(PricingModel.PER_GUEST); ratePlan.setAdultPrice(new java.math.BigDecimal("300.00")); ratePlan.setYouthPrice(new java.math.BigDecimal("275.00")); bundle.setRatePlan(ratePlan); List activityIds = getActivityIds(); int i = 0; for (Key id : activityIds) { BundledActivity bundledActivity = new BundledActivity(); bundledActivity.setDay(++i); ActivityFK activityFk = new ActivityFK(); activityFk.setKey(id); activityFk.setName("activity " + i); activityFk.setPricingModel(PricingModel.PER_GUEST); bundledActivity.setActivity(activityFk); RatePlan activityRate = new RatePlan(); activityRate.setPricingModel(PricingModel.PER_GUEST); activityRate.setAdultPrice(new java.math.BigDecimal("150.00")); activityRate.setYouthPrice(new java.math.BigDecimal("120.00")); bundledActivity.setRatePlan(activityRate); bundle.getActivities().add(bundledActivity); } PersistenceManager pm = PMF.createManager(); Transaction tx = pm.currentTransaction(); try { bundle = pm.makePersistent(bundle); tx.commit(); } finally { if (tx.isActive()) { tx.rollback(); } pm.close(); } I get the Bundle saved just fine, but when it tries to save it's child BundledActivity instances, it breaks. However, when I do the same thing through the UI of my app, I get the error when attempting to save the Bundle (i.e. nothing gets written to the datastore, where as in this test code above, the parent Bundle is getting written, but none of it's children are getting written). Of course anytime I post my code, I kind of summarize, there are utilities that I use etc. But I am able to reproduce the issue without using any of my "helper" apis. I am completely open to just sending you my code (it's all proof of concept right now, so no disclosure issues) and you can see how all the pieces I'm using are fitting together. I appreciate you taking a look at this, I'd love to know if I'm doing something wrong. thanks, -bryce On Tue, Dec 1, 2009 at 11:03 AM, Max Ross (Google) wrote: > Hi Bryce, > > Thanks for posting your model objects. I'm not able to reproduce the > exception you're reporting, but then again I'm just guessing at how you're > populating your objects and persisting them. Here's what I did: > > Bundle b = new Bundle(); > RatePlan rp = new RatePlan(); > rp.setPricingModel(PricingModel.BOTH); > b.setRatePlan(rp); > b.setPricingModel(PricingModel.PER_GUEST); > BundledActivity ba = new BundledActivity(); > ba.setDay(3); > ActivityFK activityFK = new ActivityFK(); > activityFK.setName("harold"); > activityFK.setPricingModel(PricingModel.PER_UNIT); > ba.setActivity(activityFK); > RatePlan anotherRatePlan = new RatePlan(); > ba.setRatePlan(anotherRatePlan); > b.getActivities().add(ba); > beginTxn(); > pm.makePersistent(b); > commitTxn(); > > If you can tell me how what you're doing differs from what I'm doing I can > investigate further. > > Thanks, > Max > > On Mon, Nov 30, 2009 at 5:34 PM, bcottam wrote: >> >> no one has any ideas on this? >> >> I'd really like to know if this is just a bug that will be resolved >> (in which case I'll continue to use this data model) or if there is a >> flaw in my data model/JDO usage. >> >> thanks! >> -bryce >> >> >> >> On Nov 30, 1:21 am, bcottam wrote: >> > I'm trying to save some data in my app, quite similar to almost all >> > other data I've previously saved. However, I'm now getting this stack >> > trace: >> > >> > java.lang.ClassCastException: oid is not instanceof >> > javax.jdo.identity.ObjectIdentity >> > at >> > com.resmark.client.mod
Re: [appengine-java] Re: Why is it called "Google App Engine for Java" ?
the GAE isn't cross-compiling, javac is doing the compiling (the real java compiler), so it's kind of a moot argument. The point is, the system runs java, not g-java, not pseudo-java, it's java. It just doesn't have all the libraries you want. That's all. It's written in the Java programming language (or Scala, or Groovy JRuby or anything else that runs on the JVM) and runs on a JVM... it's Java. On Tue, Dec 1, 2009 at 2:18 AM, Bobby wrote: > Suppose someone writes an app in C and wishes to cross compile to > Java. In that scenario, if some C class is unsupported by the cross- > compiler, then does the C app stop being a C app? No. > > Bobby > > On Dec 1, 4:10 am, Bobby wrote: >> Maybe for terminology's sake it would make sense to detach the GAE >> from any language associations and just indicate that there are cross- >> compilers from Java/Python to GAE. Then there would be no question on >> whether it's "technically Java" - one does write in Java, it's just >> that the cross-compiler has its own requirements and limitations. Is >> that any better? :) >> >> Bobby >> >> On Nov 30, 2:58 pm, Nicolas Melendez >> wrote: >> >> > if we are going to collaborate each other, we need the right names because >> > communication is critical. >> >> > On Mon, Nov 30, 2009 at 4:37 PM, Jess Evans wrote: >> > > There are innovators who "attempt" to advance the field and be the first. >> > > They appeal to the desperate and the early adopters with nothing to loose >> > > and much to gain. >> >> > > There are guardians with deep experience who strive to ensure reliability >> > > and predictability. They appeal to those upon whom many are dependent; >> > > those with everything to lose and little to gain. >> >> > > Both camps are invaluable. >> >> > > Incorrectly categorizing a technology, or failing to understand who >> > > you're >> > > employed to represent, are personal problems. >> >> > > On Nov 30, 2009 12:22 PM, "Jeff Schnitzer" wrote: >> >> > > I, for one, am sick and tired of Sun's domineering, suffocating >> > > stranglehold on what is and isn't Java. GAE is a breath of fresh air. >> >> > > JavaME and JavaEE also impose a variety of limitations on Java. >> > > What's the difference between those and GAE? The difference is that >> > > Sun got a committee of big company representatives with their own >> > > vested interests in a closed room and argued about how "the official >> > > specs" should work for years... and ultimately produced a bunch of >> > > crap that is barely useful to anyone. Just *try* out Websphere >> > > sometime, I dare you. >> >> > > For the first time ever, someone has produced a shared application >> > > service model for Java that's even easier than PHP. This could never >> > > have come out of the JCP. >> >> > > If this is "destroying java", then GOOD RIDDANCE! >> >> > > Jeff >> >> > > -- You received this message because you are subscribed to the Google >> > > Groups "Google App Engine fo... >> >> > > -- >> > > 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-j...@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. > > -- > > 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-j...@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. > > > -- 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-j...@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.
[appengine-java] Re: Master/Detail relations and redundant data handling
hey James, I usually do a defaultFetchGroup="true" on my embedded classes ('cause I always want them), but this makes it so that the embedded class is always loaded. This generally isn't a problem because embedded values are contained in your entities record in the data store. However, there is another approach that you can use to conditionally load your embedded (or any other) fields, the @FetchGroup annotation @FetchGroups({ @FetchGroup(name="Member.dataAuditFetchGroup", member...@persistent(name="dataAudit")}) }) @PersistenceCapable(identityType = IdentityType.APPLICATION) public class Member { ... @Persistent @Embedded private DataAudit dataAudit; } thus, in a query you could use this fetch group whenever doing a query where you knew you wanted your embedded field pre-loaded: Query q = pm.newQuery(Member.class); q.getFetchPlan().addGroup("Member.dataAuditFetchGroup"); List result = (List) q.execute(); this will go fetch all the Member records, and before giving them back to you, it will populate the dataAudit field. The name of the FetchGroup is arbitrary, I think it must be unique, but it doesn't have to have the field you are referring to in the name. You can also specify multiple fields in the FetchGroup. I think this is a really nice feature of JDO over JPA. hope that helps!! -bryce On Mon, Nov 9, 2009 at 1:29 PM, James H wrote: > > Bryce, I tried another use of your "embedded class" related to Audit > fields on an Entity. For consistency in approach to Auditing entity > data, typically you would add the following 4 fields to each entity in > your design: createBy, createdDate, updatedBy, and updatedDate. I > thought I'd place these 4 fields in an embedded class to be used by > every entity as a Best Practice to manage these 4 fields. But, I > noticed when I tried this on the first entity kind it left the embed > null after a standard Query. The code looks like this: > > @PersistenceCapable(identityType = IdentityType.APPLICATION) > public class Member { >@PrimaryKey >@Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY) >private Key memberId; >@Persistent >private Key referringMemberId; >@Persistent >private String memberType; >... >@Persistent >@Embedded >private DataAudit dataAudit; > } > > @PersistenceCapable(embeddedOnly="true") > public class DataAudit { >@Persistent >private Key createMemberId; >@Persistent >private Date createDate; >@Persistent >private Key updateMemberId; >@Persistent >private Date updateDate; > >public DataAudit() throws Exception { >createMemberId = null; >createDate = null; >updateMemberId = null; >updateDate = null; >} > >// getters/setters > } > > Sample query logic for all members: > > List list = pm.newQuery(Member.class).execute(); > > So each Member in the list is valid, except member.dataAudit is null > and I assume the query engine would populate dataAudit along with its > fields from the query automatically...as in the case with the embeds > from your examples. Any ideas? > > On Nov 5, 1:40 pm, bryce cottam wrote: >> here's a really good talk about how objects are mapped into the >> BigTable datastore and how relationships are actually represented in >> the >> system:http://sites.google.com/site/io/under-the-covers-of-the-google-app-en... >> this sort of highlites how relationships actually work in BigTable >> (which is quite different than they work in an RDB). >> >> here is another one from Max Ross where he advocates denormalization >> for query >> optimization:http://code.google.com/events/io/2009/sessions/SofterSideofSchemas.html >> he kind of goes into how the BigTable datastore is simply schema-less. >> Very interesting stuff. >> >> hope that helps. >> -bryce >> >> >> >> On Thu, Nov 5, 2009 at 12:34 PM, Rusty Wright >> wrote: >> >> > Good points. In my case, so far, the copied objects are small and not >> > complicated, which is why my method appealed to me. >> >> > I feel like there's some fundamental concept that I'm not getting and it >> > has to do with how objects are mapped onto the Big Table data store. >> > Watching the videos from Google I/O, those guys just wave their hands and >> > make it sound like it's all so easy, if you know what you're doing. >> >> > bryce cottam wrote: >> >> I don't think that duplicating the whole Department object as a child >> >> of a Person is all that go
[appengine-java] Re: Master/Detail relations and redundant data handling
here's a really good talk about how objects are mapped into the BigTable datastore and how relationships are actually represented in the system: http://sites.google.com/site/io/under-the-covers-of-the-google-app-engine-datastore this sort of highlites how relationships actually work in BigTable (which is quite different than they work in an RDB). here is another one from Max Ross where he advocates denormalization for query optimization: http://code.google.com/events/io/2009/sessions/SofterSideofSchemas.html he kind of goes into how the BigTable datastore is simply schema-less. Very interesting stuff. hope that helps. -bryce On Thu, Nov 5, 2009 at 12:34 PM, Rusty Wright wrote: > > Good points. In my case, so far, the copied objects are small and not > complicated, which is why my method appealed to me. > > I feel like there's some fundamental concept that I'm not getting and it has > to do with how objects are mapped onto the Big Table data store. Watching > the videos from Google I/O, those guys just wave their hands and make it > sound like it's all so easy, if you know what you're doing. > > > bryce cottam wrote: >> I don't think that duplicating the whole Department object as a child >> of a Person is all that good of an idea. First off, if the Department >> object gets complicated and has it's own child objects all that data >> will be living on the Person, which isn't really needed. The whole >> reason for the FK style classes is to pull over only those fields you >> would want to query on when selecting a Person object like: >> select from Person where department.name == "ABC" >> (which is something you cannot do otherwise) >> >> So, I've found that either having a list of Key (or encoded string >> ids) on a Person instance is usefull (when you are not wanting to >> query on fields of the Department when selecting a Person, >> Or having a list of lightweight copies of a Department (as opposed to >> the whole Department object) >> It seems very natural to me to determine equality of two persisted >> objects by comparing their Key instance, rather than simply their >> name. For one reason; it's somewhat difficult to ensure uniqueness >> for arbitrary fields on an object in the GAE unless that fields is >> being used to create the key (like an email address or something), if >> you are using auto-generated Keys, this isn't really an option. >> >> So, assuming you have the lightweight FK style object as a child of >> the Person class, then when the source of truth changes (i.e. the real >> Department instance), you'd need to find all lightweight FK style >> copies of that instance and update them accordingly. This is part of >> the whole root of this discussion: how do you do this in a way that >> minimized code duplication and boilerplate code blocks (like >> constructors that manually copy fields from getters to setters etc.) >> >> The solution I've been working with is the ligthweight FK style "copy" >> of the real instance of an object, and some simple reflection to map >> fields from the real object to the lightweight FK "copy". >> >> As far as detachable="true|false" my main concern with that right now >> is how the GWT RPC serializer handles detachable entities (i.e. it >> doesn't handle them well). There are certainly advantages to >> detaching an object, however, if the updates to the object are >> happening on the server, then there is no need to detach the object. >> >> >> >> On Thu, Nov 5, 2009 at 1:09 AM, Rusty Wright wrote: >>> I think this is an important point. The light bulb went off over my head >>> after watching this video. This is what he calls a property list. For me >>> it was also a good example of how to think about denormalizing, which comes >>> up repeatedly. >>> >>> So instead of the usual OO way of thinking of a department etc. aggregating >>> people, turn it on its head and look at it as a person has a property, >>> which is their department, and in this example, they can be in multiple >>> departments so it's a list of departments, a property list. As you point >>> out, the queries for this are slick. And it sounds like you don't even >>> need the list of people in the department; it's redundant. >>> >>> I'm still puzzled about what to do when a property value changes; for >>> example, suppose the department named the Ministry of Propaganda changes >>> its name to the Ministry of Disinformation.
[appengine-java] Re: Master/Detail relations and redundant data handling
I don't think that duplicating the whole Department object as a child of a Person is all that good of an idea. First off, if the Department object gets complicated and has it's own child objects all that data will be living on the Person, which isn't really needed. The whole reason for the FK style classes is to pull over only those fields you would want to query on when selecting a Person object like: select from Person where department.name == "ABC" (which is something you cannot do otherwise) So, I've found that either having a list of Key (or encoded string ids) on a Person instance is usefull (when you are not wanting to query on fields of the Department when selecting a Person, Or having a list of lightweight copies of a Department (as opposed to the whole Department object) It seems very natural to me to determine equality of two persisted objects by comparing their Key instance, rather than simply their name. For one reason; it's somewhat difficult to ensure uniqueness for arbitrary fields on an object in the GAE unless that fields is being used to create the key (like an email address or something), if you are using auto-generated Keys, this isn't really an option. So, assuming you have the lightweight FK style object as a child of the Person class, then when the source of truth changes (i.e. the real Department instance), you'd need to find all lightweight FK style copies of that instance and update them accordingly. This is part of the whole root of this discussion: how do you do this in a way that minimized code duplication and boilerplate code blocks (like constructors that manually copy fields from getters to setters etc.) The solution I've been working with is the ligthweight FK style "copy" of the real instance of an object, and some simple reflection to map fields from the real object to the lightweight FK "copy". As far as detachable="true|false" my main concern with that right now is how the GWT RPC serializer handles detachable entities (i.e. it doesn't handle them well). There are certainly advantages to detaching an object, however, if the updates to the object are happening on the server, then there is no need to detach the object. On Thu, Nov 5, 2009 at 1:09 AM, Rusty Wright wrote: > > I think this is an important point. The light bulb went off over my head > after watching this video. This is what he calls a property list. For me it > was also a good example of how to think about denormalizing, which comes up > repeatedly. > > So instead of the usual OO way of thinking of a department etc. aggregating > people, turn it on its head and look at it as a person has a property, which > is their department, and in this example, they can be in multiple departments > so it's a list of departments, a property list. As you point out, the > queries for this are slick. And it sounds like you don't even need the list > of people in the department; it's redundant. > > I'm still puzzled about what to do when a property value changes; for > example, suppose the department named the Ministry of Propaganda changes its > name to the Ministry of Disinformation. Does the property list on Person > contain a list of Department objects, or a list of Department Key objects? > I'm thinking the former, Department objects. If we have the Department class > configured with detachable="false", each time you fetch a Department object > (matching on its name let's say), you get a new unparented Department object, > which you add to the Person's department list, whereupon it becomes parented > by Person. The fetched Department object is essentially a clone. (That's > assuming I understand how it works when you have detachable="false"; it's > sort of like the singleton pattern.) As part of fetching the cloned > Department object, the Department class has a masterKey field, type Key, > which you set to the Key of the Department in the table, the one it was > cloned from. So whe > n the Department's name changes, the query to get all its cloned Departments > could be simple and quick. But now I'm fuzzy on how you change the master > Department's name; since it's detachable="false" we can't fetch it and update > it and save it back, so I guess we have to replace it in the master table and > then replace all of its clones in all Person lists? > > > bryce cottam wrote: >> ah, gottcha, well there is actually a really good google i/o talk on >> using list/collections and how to optimize them. I generally am using >> "owned" lists for smaller collections,and un-owned ones are >> represented by the child object containing an FK type class as a >
[appengine-java] Re: Master/Detail relations and redundant data handling
Hi James, sorry for the delay, My design is currently similar to what you proposed. However, in your example, I'd probably make 2 classes: PersonFK and InstitutionFK.: public class PersonFK { private Key id; private String firstName; private String lastName; private String city; } public class InstitutionFK { private Key id; private String name; private String city; } Then in Person you would have: public class Person { private List institutions; } and in Institutions you would have: public class Institution { private List persons; } (I'm leaving out the annotations for brevity). each of these member fields (institutions and persons) are "owned" by their containing instance of Person and Institutions. Thus, the relationship is defined by who owns it (i.e we don't need the Institution's id, name, city etc. on the persons collection because we already know what Institution the PersonFK's are linked to) So, yes, anytime you want to do something like update the Person.city field, you'd want to get all PersonFK instances with your person-Id, then update each instance with the "new" city value. Of course, this only matters if you plan on querying Institutions based off of the "city" field of a Person. That generally would imply multiple transactions, however there is the Wilkerson distributed transaction model, which makes "global" transactions on GAE possible. So, if your writes really do need to be transactional, then you can do an "all or nothing" operation on multiple entity groups with this approach. here is a video from Google I/O about distributed transactions on the GAE: http://www.youtube.com/watch?v=IOtBlzsx0m8 On Tue, Nov 3, 2009 at 1:50 PM, James H wrote: > > Consider this test case. A Person belongs to 1 or more Institutions > so there's 2 ways you would want to query this. Query #1: Given a > particular Person then which Institutions does he belong to? Query > #2: Given a particular Institution then which Persons are members? > > Assume entity Person and its associated child relations will form its > own entity group and, likewise, entity Institution will form its own > entity group related to its children. In order to accommodate large > amounts of Person and Institution data, I submit that you would need > "owned" relations of each. > > Therefore, you would need entity PersonInstitutions as an owned child > relation with Person for Query #1. Similarly, you would need entity > InstitutionPersons as an owned child relation with Institution for > Query #2. > > Also, each of these 2 child entities would contain both a PersonFK and > a InstitutionFK with appropriate redundant fields ancillary to the > query requirement of the app. Again, the embedded FK class avoids > extra queries that would kill search list performance, etc. For > example with Query #2, give me all persons at Baylor that have first > name James would only need the entity InstitutionPersons. > > So, we accept the fact the design requires redundant data in the > embedded FK class but at least from a source code perspective we only > have FK class to manage. > > Is it correct that we would need both "owned" relations or not? Say > you had Persons and Institutions from around the world. I can't > imagine satisfying the above 2 queries without both "owned" > relations. Of course, this means updates to both relations are across > 2 entity groups and separate transactions. Another fact we have to > accept in the design right? > > On Nov 3, 2:22 pm, James H wrote: >> Ok Bryce...I'm back. Going to test with your ideas now. In my case, >> I tend to avoid generic column names like "id" in favor of "bookId" >> and "chapterId" so I should not have any naming conflicts (at least >> rarely). Also, my FK embedded classes should not have any collections >> though I have a feeling they may come up as I get further into it. >> >> I'll just test with Book and owned relation Chapter as you have it >> here. How do we tell JDO whether a relation is "owned" vs "unowned" >> by the way? Because I would like to have a child object of each for >> the testing. Thanks! >> >> On Oct 9, 12:06 pm, bryce cottam wrote: >> >> >> >> > FYI, this video was hugely helpful for me, and this information helps >> > me decide how to structure my data model to run best on the >> > app-engine, it's a Google I/O session on how the app-engine big table >> > implementation works:http://www.youtube.com/watch?v=tx5gdoNpcZM >> >> > On Fri, Oct 9, 2009 at 10:
[appengine-java] Re: Master/Detail relations and redundant data handling
Sounds good James. The owned relationship between Book and Chapter is just defined by the fact that Book has a collection of Chapter as a member variable. If the relationship is bi-directional (i.e. Chapter has a Book as a member variable) then you use the mappedBy field in the @Persistent annotation. Looking foreward to youre feedback. On Nov 3, 2009 1:22 PM, "James H" wrote: Ok Bryce...I'm back. Going to test with your ideas now. In my case, I tend to avoid generic column names like "id" in favor of "bookId" and "chapterId" so I should not have any naming conflicts (at least rarely). Also, my FK embedded classes should not have any collections though I have a feeling they may come up as I get further into it. I'll just test with Book and owned relation Chapter as you have it here. How do we tell JDO whether a relation is "owned" vs "unowned" by the way? Because I would like to have a child object of each for the testing. Thanks! On Oct 9, 12:06 pm, bryce cottam wrote: > FYI, this video was hugely helpful fo... > On Fri, Oct 9, 2009 at 10:46 AM, James H wrote: > > > Ylmz, thats how... > ... > > read more »- Hide quoted text - > > - Show quoted text - --~--~-~--~~-... --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---
[appengine-java] type safe keys?
In my app (as in many apps I imagine) there are relationships that I end up managing in the code. For instance, a Parent class with a list of Child instances. In order to make each child in it's own entity group, I have the list of children defined on the Parent as List children; and on the Child class, I've got a Key instance that is a reference to the parent. Key parentKey; However, there is no way that I can seen to ensure that the entity referenced by any given Key instance in my list is indeed an instance of Child, or that the Key on the Child instance actually points to an instance of a Parent. I remember reading some kind of enhancement request looking for some kind of generically typed Key class, something like: Key so, in order to have a Key you know is of a certain type you do: List> children; or something similar. And for the Child's reference to it's parent you'd do: Key parentKey; has anyone found a good way to get some type safety with respect to Keys? 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 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 -~--~~~~--~~--~--~---