Java 从Google数据存储获取对象后,该对象为空

Java 从Google数据存储获取对象后,该对象为空,java,google-app-engine,google-cloud-datastore,Java,Google App Engine,Google Cloud Datastore,在问是否可以用Java将复杂的类组合保存到GoogleAppengine中的GoogleDatastore之前,我问过,但是我不够清楚,也懒得发布我的所有类,但经过长时间的努力,我开始放弃。下面是代码中更详细的问题 我知道这类东西应该很好用,但不知什么原因,这不起作用。问题是,当我保存对象并关闭db连接,然后再次打开它时,该对象中的数据为空。该对象在数据库中,当我选择该对象的ID时可以看到它,但其他所有内容都为空。不幸的是,谷歌没有数据库查看器来查看数据库中的内容。我试着寻找一个,但没有运气。(

在问是否可以用Java将复杂的类组合保存到GoogleAppengine中的GoogleDatastore之前,我问过,但是我不够清楚,也懒得发布我的所有类,但经过长时间的努力,我开始放弃。下面是代码中更详细的问题

我知道这类东西应该很好用,但不知什么原因,这不起作用。问题是,当我保存对象并关闭db连接,然后再次打开它时,该对象中的数据为空。该对象在数据库中,当我选择该对象的ID时可以看到它,但其他所有内容都为空。不幸的是,谷歌没有数据库查看器来查看数据库中的内容。我试着寻找一个,但没有运气。(有,但没有) 那么,我们开始吧:

内容

// imports...
@PersistenceCapable(identityType = IdentityType.APPLICATION)
public class Content{

 @PrimaryKey
 @Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
 @Extension(vendorName="datanucleus", key="gae.encoded-pk", value="true")
 private String id;

 @Persistent protected String title;
 @Persistent protected String thumbnailURL;
 @Persistent protected List<Rating> ratings;
 @Persistent protected List<Tag> tags;
 @Persistent protected Double price;
 @Persistent protected User owner;

 // constructor and getters+setters
}
// imports...
@PersistenceCapable(identityType = IdentityType.APPLICATION)
public class Document extends Content /*AthenaObject*/ {
 @PrimaryKey
 @Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
 @Extension(vendorName="datanucleus", key="gae.encoded-pk", value="true") 
 private String id;

 @Persistent private String docUrl;

 // constructor and getters+setters
}
视频

// imports...
public class Video extends Content {
  @PrimaryKey
  @Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
  @Extension(vendorName="datanucleus", key="gae.encoded-pk", value="true")
  String id;

  @Persistent String fileUrl;

  // constructor and getters+setters
}
文档

// imports...
@PersistenceCapable(identityType = IdentityType.APPLICATION)
public class Content{

 @PrimaryKey
 @Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
 @Extension(vendorName="datanucleus", key="gae.encoded-pk", value="true")
 private String id;

 @Persistent protected String title;
 @Persistent protected String thumbnailURL;
 @Persistent protected List<Rating> ratings;
 @Persistent protected List<Tag> tags;
 @Persistent protected Double price;
 @Persistent protected User owner;

 // constructor and getters+setters
}
// imports...
@PersistenceCapable(identityType = IdentityType.APPLICATION)
public class Document extends Content /*AthenaObject*/ {
 @PrimaryKey
 @Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
 @Extension(vendorName="datanucleus", key="gae.encoded-pk", value="true") 
 private String id;

 @Persistent private String docUrl;

 // constructor and getters+setters
}
标记

// imports...
@PersistenceCapable(identityType = IdentityType.APPLICATION)
public class Tag{
 @PrimaryKey
 @Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
 @Extension(vendorName="datanucleus", key="gae.encoded-pk", value="true")
 private String id;

 @Persistent private String tagText;

 // constructor and getters+setters
}
用于持久化和从数据存储中获取数据的代码:

public Boolean testCourse(){
 Boolean isSaved = false;
 PersistenceManager pm = PMF.get().getPersistenceManager();
 Course c = new Course();
 try{
  List<Tag> tags = new ArrayList<Tag>();
  tags.add(new Tag("tag1"));
  tags.add(new Tag("tag2"));
  tags.add(new Tag("tag3"));


  c.setTitle("Course Title - " + new Date().getTime());
  c.setPrice(99.90);
  c.setTags(tags);

  System.out.println(c.toString()); // **Output:** ID: null Title: Course Title - 1247116147858, Price: 99.9, No. of Tags: 3
  pm.makePersistent(c);

  Course cAfter = pm.getObjectById(Course.class, KeyFactory.stringToKey(c.getId()));
  System.out.println(cAfter.toString()); // **Output:** agptYRtzaWL4gZDb3Vy4ErYFgw Title: Course Title - 1247116147858, Price: 99.9, No. of Tags: 3
  isSaved = true;
 }
 catch(Exception e){
  e.printStackTrace();
  isSaved = false;
 }
 finally{
  pm.close();
 }


 pm = PMF.get().getPersistenceManager();

 try{

  Course cAfterClose = pm.getObjectById(Course.class, KeyFactory.stringToKey(c.getId()));
  System.out.println(cAfterClose.toString()); // **Error**: See below
 }
 catch(Exception e){e.printStackTrace();}
 finally{pm.close();}


 return isSaved;
}
public Boolean testCourse(){
布尔值isSaved=false;
PersistenceManager pm=PMF.get().getPersistenceManager();
课程c=新课程();
试一试{
列表标记=新的ArrayList();
添加(新标签(“tag1”);
添加(新标签(“tag2”);
添加(新标签(“tag3”);
c、 setTitle(“课程名称-”+新日期().getTime());
c、 设定价格(99.90),;
c、 设置标签(标签);
System.out.println(c.toString());//**输出:**ID:null标题:课程标题-1247116147858,价格:99.9,标签数量:3
项目经理(c);
Course cAfter=pm.getObjectById(Course.class,KeyFactory.stringToKey(c.getId());
System.out.println(cAfter.toString());/**输出:**agptYRtzaWL4gZDb3Vy4ErYFgw标题:课程标题-1247116147858,价格:99.9,标签数量:3
isSaved=真;
}
捕获(例外e){
e、 printStackTrace();
isSaved=假;
}
最后{
pm.close();
}
pm=PMF.get().getPersistenceManager();
试一试{
Course-cAfterClose=pm.getObjectById(Course.class,KeyFactory.stringToKey(c.getId());
System.out.println(cAfterClose.toString());//**错误**:见下文
}
catch(异常e){e.printStackTrace();}
最后{pm.close();}
保留了回报;
}
以下是输出:

ID:nullTitle:课程名称- 1247117389679,价格:99.9,数量 标签:3 ID:AGPTYWTZAW1ZYXBWCGWLEGZDB3VYC2VYCAWTITLE: 课程名称-1247117389679,价格: 99.9,标记数:3 java.lang.NullPointerException位于 com.athena.server.entity.Course.toString(Course.java:94) 在 com.athena.server.CourseServiceImpl.testCourse(CourseServiceImpl.java:146) 在 sun.reflect.NativeMethodAccessorImpl.invoke0(本机 方法)在 invoke(NativeMethodAccessorImpl.java:39) 在 reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) 在 java.lang.reflect.Method.invoke(Method.java:585) 在 com.google.gwt.user.server.rpc.rpc.invokeAndEncodeResponse(rpc.java:527) 在 com.google.gwt.user.server.rpc.RemoteServiceServlet.processCall(RemoteServiceServlet.java:166) 在 com.google.gwt.user.server.rpc.RemoteServiceServlet.doPost(RemoteServiceServlet.java:86) 在 javaservlet.http.HttpServlet.service(HttpServlet.java:713) 在 javaservlet.http.HttpServlet.service(HttpServlet.java:806) 在 org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:487) 在 org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1093) 在 com.google.apphosting.utils.servlet.TransactionCleanupFilter.doFilter(TransactionCleanupFilter.java:43) 在 org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1084) 在 org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:360) 在 org.mortbay.jetty.security.SecurityHandler.handle(SecurityHandler.java:216) 在 org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:181) 在 org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:712) 在 org.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java:405) 在 com.google.apphosting.utils.jetty.DevAppEngineWebAppContext.handle(DevAppEngineWebAppContext.java:54) 在 org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:139) 在 com.google.appengine.tools.development.JettyContainerService$ApiProxyHandler.handle(JettyContainerService.java:306) 在 org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:139) 在 org.mortbay.jetty.Server.handle(Server.java:313) 在 org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:506) 在 org.mortbay.jetty.HttpConnection$RequestHandler.content(HttpConnection.java:844) 在 org.mortbay.jetty.HttpParser.parseNext(HttpParser.java:644) 在 org.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java:211) 在 org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:381) 在 org.mortbay.io.nio.SelectChannelEndPoint.run(SelectChannelEndPoint.java:396) 在 org.mortbay.thread.BoundedThreadPool$PoolThread.run(BoundedThreadPool.java:442)

我知道这个错误意味着字符串为空。但记录在数据库中。应该坚持下去。为什么数据是空白的


有什么建议可以解释为什么我会出现这种情况吗?

我不知道到底是什么原因导致了您的错误,但以下是一些您可以尝试帮助排除故障的步骤:

首先,试着把你的问题缩小到一个尽可能小的测试用例。上面发布了很多类,很可能只有2个或3个类会重复这个问题

第二,如果你真的想看到你的实体在数据存储中的样子,你必须这样做(或者你可以尝试将你的应用上传到appengine并在那里运行,这样你就可以使用他们的dataviewer):

Query q=pm.newQuery(Course.class);
List=(List)q.execute();
用于(课程c:列表){
System.out.println(“课程id: