I've got some classes that extend a base class.  This base class
implements some simple functions (like hashCode() and equals() ect.)
in a generic way so I don't have to keep writing those methods over...
and over... and over again.  It also is the central place for entities
"id" field:



@Inheritance(customStrategy = "complete-table")
@PersistenceCapable(identityType=IdentityType.APPLICATION)
public class BaseBean implements IsSerializable, Serializable,
Identifiable
{
        private static final long serialVersionUID = 1L;

        @NotPersistent
        private Integer hash;

        @PrimaryKey
        @Persistent(valueStrategy=IdGeneratorStrategy.IDENTITY)
        private Key id;

        @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;
        }

        .... getters/setters...
}

pretty much every entity class in my model extends this class.

I didn't have to have the jdo annotations on this class in 1.2.6,
however, right after upgrading to 1.2.8, I had to make this class
PersistenceCapable otherwise datanucleus started to complain that it
wasn't enhanced (which, was never a problem before)  In fact, this
class isn't persisted, there's never a case where the runtime of a
persisted bean is ever BaseBean (it's always an instance of a sub-
class).  So, I added the above annotations, and things were working
fine, until later on in my tests, I had a class with multiple
relationships.  I.E. this class has a one-to-one relationship with
class A and a one-to-many relationship with instances of class B (both
of which extend BaseBean, but otherwise share no inheritence
attributes):


@PersistenceCapable(identityType=IdentityType.APPLICATION)
public class ActivityReservation extends BaseBean implements
Comparable<ActivityReservation>
{
        @Embedded(
                members={
                                @Persistent(name="key", column="activityKey"),
                                @Persistent(name="name", column="name"),
                                @Persistent(name="pricingModel", 
column="pricingModel")
                }
        )
        @Persistent(defaultFetchGroup="true")
        private ActivityFK activity;

        @Embedded
        @Persistent(defaultFetchGroup="true")
        private ActivityLaunchFK launch;

        @Persistent
        private RatePlan ratePlan;
        @Persistent
        private BigDecimal totalCost;
        @Persistent
        private List<Guest> guests = new ArrayList<Guest>();
       .... getters/setters...
}

@PersistenceCapable(identityType=IdentityType.APPLICATION)
public class RatePlan extends BaseBean
{
        @Persistent
        private String name;

        @Persistent
        private BigDecimal adultPrice;
        @Persistent
        private BigDecimal youthPrice;
        @Persistent
        private BigDecimal unitPrice;

        @Persistent
        private PricingModel pricingModel;

        @Persistent
        private boolean active = true;
        .....
}

simple enum:
public enum PricingModel implements IsSerializable, Serializable
{

        PER_GUEST("Per Guest"),
        PER_UNIT("Per Unit"),
        BOTH("Both");

        private final String label;

        private PricingModel(String label)
        {
                this.label = label;
        }

        public String getLabel()
        {
                return label;
        }

        public String toString()
        {
                return getLabel();
        }
}



embedded classes (these don't extend BaseBean):
@PersistenceCapable(identityType=IdentityType.NONDURABLE)
public class ActivityFK
{
        @Persistent
        private Key key;
        @Persistent
        private String name;
        @Persistent
        private PricingModel pricingModel;

}

@PersistenceCapable(identityType=IdentityType.NONDURABLE)
public class ActivityLaunchFK extends
AbstractKeyReference<ActivityLaunch>
{
        @Persistent
        private Key key;
        @Persistent
        private Date startDate;
        @Persistent
        private Date endDate;
}


here is the stack trace I am getting:
Error in meta-data for
com.resmark.client.model.ActivityReservation.ratePlan: Class
com.resmark.client.model.ActivityReservation has multiple relationship
fields of type com.resmark.client.model.BaseBean.  This is not yet
supported.
        at
org.datanucleus.jdo.NucleusJDOHelper.getJDOExceptionForNucleusException
(NucleusJDOHelper.java:354)
        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.createReservation
(SetupServiceImpl.java:83)
        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)



I'm assuming the error is coming from ActivityReservation's
relationship with RatePlan (one-to-one) and Guest (one-to-many).
Datanucleus seems to think that there are both the same type (because
they both extend BaseBean) however this is clearly not true.

So, I wonder if I'm "resolving" the BaseBean with @PersistenceCapable
(which I never did before i.e. it was a POJO without any JDO
annotations on it) or if this is a bug.

any help/feedback is appreciated

-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-java?hl=en.


Reply via email to