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.