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 <[email protected]> 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(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 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. > org.datanucleus.store.exceptions.NoTableManagedException: 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.store.appengine.DatastoreManager.getDatastoreClass(DatastoreManager.java:644) > at > org.datanucleus.store.appengine.DatastoreManager.getDatastoreClass(DatastoreManager.java:82) > at > org.datanucleus.store.appengine.DatastoreTable.initializeNonPK(DatastoreTable.java:428) > at > org.datanucleus.store.appengine.DatastoreTable.buildMapping(DatastoreTable.java:285) > at > org.datanucleus.store.appengine.DatastoreManager.buildStoreData(DatastoreManager.java:405) > at > org.datanucleus.store.appengine.DatastoreManager.newStoreData(DatastoreManager.java:363) > at > org.datanucleus.store.AbstractStoreManager.addClasses(AbstractStoreManager.java:788) > at > org.datanucleus.store.AbstractStoreManager.addClass(AbstractStoreManager.java:759) > at > org.datanucleus.store.mapped.MappedStoreManager.getDatastoreClass(MappedStoreManager.java:358) > at > org.datanucleus.store.appengine.DatastoreManager.getDatastoreClass(DatastoreManager.java:631) > at > org.datanucleus.store.appengine.DatastoreFieldManager.buildMappingConsumer(DatastoreFieldManager.java:1008) > at > org.datanucleus.store.appengine.DatastoreFieldManager.buildMappingConsumer(DatastoreFieldManager.java:998) > at > org.datanucleus.store.appengine.DatastoreFieldManager.<init>(DatastoreFieldManager.java:133) > at > org.datanucleus.store.appengine.DatastoreFieldManager.<init>(DatastoreFieldManager.java:167) > at > org.datanucleus.store.appengine.DatastorePersistenceHandler.insertPreProcess(DatastorePersistenceHandler.java:316) > at > org.datanucleus.store.appengine.DatastorePersistenceHandler.insertObjects(DatastorePersistenceHandler.java:236) > 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.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) > > so, this does indeed look like problem with the > org.datanucleus.store.appengine.DatastoreManager in the > getDatastoreClass method. Hopefully someone on that team sees this > post. > > thanks so much for your input! > -bryce > > > > On Mon, Dec 7, 2009 at 2:13 AM, datanucleus <[email protected]> > wrote: > > Let's be clear here, if you have > > public class Base > > { > > private long id; > > > > public long getId() > > { > > return id; > > } > > > > public void setId(long id) > > { > > this.id = id; > > } > > } > > @PersistenceCapable > > public class Sub extends Base > > { > > @PrimaryKey > > @Persistent > > public long getId() > > { > > return super.getId(); > > } > > public void setId(long id) > > { > > super.setId(id); > > } > > } > > > > and persist a Sub, then ***DataNucleus*** will *not* insist that the > > superclass is persistable. This is based on all DN datastore plugins > > except GAE/J. If GAE/J does cause this then it is a bug in that plugin > > and raise a bug on them, with stack trace and exception etc etc. > > > > Also to be clear, the JDO and JPA specs do *not* allow magical > > persistence of a field of a non-persistable superclass, unless you do > > an override in a subclass like what you did there (to make it a > > persistable property). You will *always* need that override. > > > > -- > > > > You received this message because you are subscribed to the Google Groups > "Google App Engine for Java" group. > > To post to this group, send email to > [email protected]. > > To unsubscribe from this group, send email to > [email protected]<google-appengine-java%[email protected]> > . > > For more options, visit this group at > http://groups.google.com/group/google-appengine-java?hl=en. > > > > > > > > -- > > You received this message because you are subscribed to the Google Groups > "Google App Engine for Java" group. > To post to this group, send email to > [email protected]. > To unsubscribe from this group, send email to > [email protected]<google-appengine-java%[email protected]> > . > For more options, visit this group at > http://groups.google.com/group/google-appengine-java?hl=en. > > > -- You received this message because you are subscribed to the Google Groups "Google App Engine for Java" group. To post to this group, send email to [email protected]. To unsubscribe from this group, send email to [email protected]. For more options, visit this group at http://groups.google.com/group/google-appengine-java?hl=en.
