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 [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.