在Java中使用AppEngine和EntityManager将记录存储到Google数据存储时出错

在Java中使用AppEngine和EntityManager将记录存储到Google数据存储时出错,java,google-app-engine,Java,Google App Engine,我试图创建一个Web服务,允许用户向数据存储中添加新记录,并显示一个充满结果的表。按下“提交”按钮时,web浏览器上会出现以下错误:- javax.persistence.PersistenceException: Invalid primary key for com.epware.gae.java.books.model.Book. Cannot have a null primary key field if the field is unencoded and of type Stri

我试图创建一个Web服务,允许用户向数据存储中添加新记录,并显示一个充满结果的表。按下“提交”按钮时,web浏览器上会出现以下错误:-

javax.persistence.PersistenceException: Invalid primary key for com.epware.gae.java.books.model.Book.  Cannot have a null primary key field if the field is unencoded and of type String.  Please provide a value or, if you want the datastore to generate an id on your behalf, change the type of the field to Long.
at org.datanucleus.api.jpa.NucleusJPAHelper.getJPAExceptionForNucleusException(NucleusJPAHelper.java:302)
at org.datanucleus.api.jpa.JPAEntityManager.close(JPAEntityManager.java:197)
at com.epware.gae.java.books.dao.Dao.add(Dao.java:27)
at com.democo.gae.java.books.ServletCreateTodo.doPost(ServletCreateTodo.java:32)
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.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:127)
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:43)
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:491)
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:212)
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: org.datanucleus.exceptions.NucleusFatalUserException: Invalid primary key for com.epware.gae.java.books.model.Book.  Cannot have a null primary key field if the field is unencoded and of type String.  Please provide a value or, if you want the datastore to generate an id on your behalf, change the type of the field to Long.
at com.google.appengine.datanucleus.StoreFieldManager.storeStringPKField(StoreFieldManager.java:599)
at com.google.appengine.datanucleus.StoreFieldManager.storeStringField(StoreFieldManager.java:158)
at org.datanucleus.state.AbstractStateManager.providedStringField(AbstractStateManager.java:1433)
at com.epware.gae.java.books.model.Book.jdoProvideField(Book.java)
at com.epware.gae.java.books.model.Book.jdoProvideFields(Book.java)
at org.datanucleus.state.AbstractStateManager.provideFields(AbstractStateManager.java:1515)
at com.google.appengine.datanucleus.DatastorePersistenceHandler.insertObjectsInternal(DatastorePersistenceHandler.java:241)
at com.google.appengine.datanucleus.DatastorePersistenceHandler.insertObject(DatastorePersistenceHandler.java:218)
at org.datanucleus.state.JDOStateManager.internalMakePersistent(JDOStateManager.java:2381)
at org.datanucleus.state.JDOStateManager.flush(JDOStateManager.java:3778)
at org.datanucleus.ObjectManagerImpl.flushInternalWithOrdering(ObjectManagerImpl.java:3888)
at org.datanucleus.ObjectManagerImpl.flushInternal(ObjectManagerImpl.java:3811)
at org.datanucleus.ObjectManagerImpl.flush(ObjectManagerImpl.java:3751)
at org.datanucleus.ObjectManagerImpl.preCommit(ObjectManagerImpl.java:4141)
at org.datanucleus.ObjectManagerImpl.transactionPreCommit(ObjectManagerImpl.java:428)
at org.datanucleus.TransactionImpl.internalPreCommit(TransactionImpl.java:398)
at org.datanucleus.TransactionImpl.commit(TransactionImpl.java:287)
at org.datanucleus.ObjectManagerImpl.close(ObjectManagerImpl.java:1090)
at org.datanucleus.api.jpa.JPAEntityManager.close(JPAEntityManager.java:193)
... 39 more
目前,对象的制作方式如下:-

public class Book 
{
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String title;
    private String author;
    private String description;
    private String publisher;
    private String publishDate;

    public Book(String title, String authorFirst, String authorSecond, String description, String publisher, String publishDate) {
        this.title = title;
        this.author = authorFirst+" "+authorSecond;
        this.description = description;
        this.publisher = publisher;
        this.publishDate = publishDate;
    }

    //Setters and Getters Below
}

如何修复它,以便将数据输入到表中?我不完全理解错误消息是怎么说的,但我相当肯定它与对象本身是如何生成的有关。非常感谢您提供有关如何解决此问题的任何帮助。

实体必须具有默认构造函数

因此,为了解决这个问题,您需要将此添加到您的代码中:

public Book()
{
}

我不知道创建一个不使用实体的构造函数如何在允许我使用数据存储的同时修复主键错误。