oh, forgot to mention:
if "according to the JDO specs" a non-persistent super class can have
a field that is overridden by it's persistent sub-classes, then it
seems like a bug that I was getting runtime errors saying that
BaseBean isn't persistable when trying to persist a subclass of
BaseBean that was persistable:

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)


that stack trace comes from this model:
public abstract class BaseBean implements IsSerializable,
Serializable, Identifiable
{
        private static final long serialVersionUID = 1L;
        
        private Integer hash;
        
        @Override
        @SuppressWarnings("unchecked")
        public boolean equals(Object obj)
        {
                if (this == obj)
                {
                        return true;
                }
                if (obj == null)
                {
                        return false;
                }
                
                boolean equal = false;
                if (getClass().equals(obj.getClass()))
                {
                        BaseBean that = (BaseBean) obj;
                        Object thisId = this.getId();
                        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<RatePlan> ratePlans = new ArrayList<RatePlan>();
}

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 <[email protected]> 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 <[email protected]> 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 [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.


Reply via email to