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) <[email protected]> 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 <[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]. >> > 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. >> >> > > -- > > You received this message because you are subscribed to the Google Groups > "Google App Engine for Java" group. > To post to this group, send email to [email protected]. > To unsubscribe from this group, send email to > [email protected]. > For more options, visit this group at > http://groups.google.com/group/google-appengine-java?hl=en. > -- You received this message because you are subscribed to the Google Groups "Google App Engine for Java" group. To post to this group, send email to [email protected]. To unsubscribe from this group, send email to [email protected]. For more options, visit this group at http://groups.google.com/group/google-appengine-java?hl=en.
