I am building an Android App with the backend hosted on GAE. Right now I am trying to persist a POJO entity through Objectify to the Datastore. Following are the POJOs I am trying to persist.
@Entity
public class GenericLearnerProfile {
private String mName;
@Id
private String mEmailID;
private String mPhoneNo;
private String mImagePath;
private String mCurrentStatus;
private String mPassword;
//Default constructor required for persistence(serialization)
public GenericLearnerProfile(){}
//.......Other Getters, Setters and constructors follow
}
@Entity
public class TutorProfile extends GenericLearnerProfile {
private EducationalQualification[] educationalQualifications;
private Occupation occupation;
//Default constructor required for persistence(serialization)
public TutorProfile(){}
//.......Other Getters, Setters and constructors follow
}
As you can see, its a pretty simple hierarchy.
Problem: When I try to persist just GenericLearnerProfile, it successfully happens but with TutorProfile, it throws out the following exception:
com.googlecode.objectify.SaveException: Error saving com.learncity.backend.persistence.TutorProfile@22fc69b4: id cannot be zero
at com.googlecode.objectify.impl.EntityMetadata.save(EntityMetadata.java:95)
at com.googlecode.objectify.impl.WriteEngine.save(WriteEngine.java:73)
at com.googlecode.objectify.impl.SaverImpl.entities(SaverImpl.java:60)
at com.googlecode.objectify.impl.SaverImpl.entity(SaverImpl.java:35)
at com.learncity.backend.persistence.TutorProfileEndpoint.insert(TutorProfileEndpoint.java:83)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.google.appengine.tools.development.agent.runtime.Runtime.invoke(Runtime.java:130)
at com.google.api.server.spi.SystemService.invokeServiceMethod(SystemService.java:363)
at com.google.api.server.spi.SystemServiceServlet.execute(SystemServiceServlet.java:113)
at com.google.api.server.spi.SystemServiceServlet.doPost(SystemServiceServlet.java:71)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:637)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
at org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:511)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1166)
at com.googlecode.objectify.ObjectifyFilter.doFilter(ObjectifyFilter.java:48)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
at com.google.appengine.api.socket.dev.DevSocketFilter.doFilter(DevSocketFilter.java:74)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
at com.google.appengine.tools.development.ResponseRewriterFilter.doFilter(ResponseRewriterFilter.java:128)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
at com.google.appengine.tools.development.HeaderVerificationFilter.doFilter(HeaderVerificationFilter.java:34)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
at com.google.appengine.api.blobstore.dev.ServeBlobFilter.doFilter(ServeBlobFilter.java:63)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
at com.google.apphosting.utils.servlet.TransactionCleanupFilter.doFilter(TransactionCleanupFilter.java:50)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
at com.google.appengine.tools.development.StaticFileFilter.doFilter(StaticFileFilter.java:125)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
at com.google.appengine.tools.development.DevAppServerModulesFilter.doDirectRequest(DevAppServerModulesFilter.java:366)
at com.google.appengine.tools.development.DevAppServerModulesFilter.doDirectModuleRequest(DevAppServerModulesFilter.java:349)
at com.google.appengine.tools.development.DevAppServerModulesFilter.doFilter(DevAppServerModulesFilter.java:116)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
at org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:388)
at org.mortbay.jetty.security.SecurityHandler.handle(SecurityHandler.java:216)
at org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:182)
at org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:765)
at org.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java:418)
at com.google.appengine.tools.development.DevAppEngineWebAppContext.handle(DevAppEngineWebAppContext.java:98)
at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
at com.google.appengine.tools.development.JettyContainerService$ApiProxyHandler.handle(JettyContainerService.java:513)
at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
at org.mortbay.jetty.Server.handle(Server.java:326)
at org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:542)
at org.mortbay.jetty.HttpConnection$RequestHandler.content(HttpConnection.java:938)
at org.mortbay.jetty.HttpParser.parseNext(HttpParser.java:755)
at org.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java:218)
at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:404)
at org.mortbay.io.nio.SelectChannelEndPoint.run(SelectChannelEndPoint.java:409)
at org.mortbay.thread.QueuedThreadPool$PoolThread.run(QueuedThreadPool.java:582)
Caused by: java.lang.IllegalArgumentException: id cannot be zero
at com.google.appengine.api.datastore.KeyFactory.createKey(KeyFactory.java:52)
at com.google.appengine.api.datastore.KeyFactory.createKey(KeyFactory.java:47)
at com.googlecode.objectify.util.DatastoreUtils.createKey(DatastoreUtils.java:77)
at com.googlecode.objectify.impl.KeyMetadata.getRawKey(KeyMetadata.java:187)
at com.googlecode.objectify.impl.translate.EntityCreator.save(EntityCreator.java:54)
at com.googlecode.objectify.impl.translate.EntityCreator.save(EntityCreator.java:16)
at com.googlecode.objectify.impl.translate.ClassTranslator.saveSafe(ClassTranslator.java:136)
at com.googlecode.objectify.impl.translate.ClassTranslator.saveSafe(ClassTranslator.java:21)
at com.googlecode.objectify.impl.translate.NullSafeTranslator.save(NullSafeTranslator.java:25)
at com.googlecode.objectify.impl.translate.ArrayTranslatorFactory$1.save(ArrayTranslatorFactory.java:83)
at com.googlecode.objectify.impl.translate.ArrayTranslatorFactory$1.save(ArrayTranslatorFactory.java:39)
at com.googlecode.objectify.impl.PropertyPopulator.save(PropertyPopulator.java:135)
at com.googlecode.objectify.impl.translate.ClassPopulator.save(ClassPopulator.java:153)
at com.googlecode.objectify.impl.translate.ClassTranslator.saveSafe(ClassTranslator.java:138)
at com.googlecode.objectify.impl.translate.ClassTranslator.saveSafe(ClassTranslator.java:21)
at com.googlecode.objectify.impl.translate.NullSafeTranslator.save(NullSafeTranslator.java:25)
at com.googlecode.objectify.impl.EntityMetadata.save(EntityMetadata.java:89)
... 51 more
Note:
- All the embedded objects have long as an Id.
- It doesn't help if I make them Long. It then displays the error - "id cannot be null"
- I don't want to manually set the long ids for the embedded objects because it really doesn't make sense for the classes to necessarily have an id(other than for persistence)
Can anyone help me understand this exception and way around it?
@Entityclasses? They will be stored as separate kinds in the datastore. If you want true polymoprhism and the ability to query across the types, you should use@Subclasson the subclasses. - stickfigure