从Google Datastore获取对象后,该对象为空白

时间:2009-07-09 05:32:51

标签: java google-app-engine google-cloud-datastore

asked question之前询问是否可以将复杂的类组合保存到Google AppEngine with Java中的Google数据存储区中,但我不够清楚并且懒得发布所有课程但是经过很长时间斗争我开始放弃了。所以这里有更详细的代码问题。

我知道这种东西应该可以正常工作,但由于某些未知的原因,这不起作用。问题是,当我保存我的对象并关闭数据库连接然后再次打开它时,该对象中的数据是空白的。对象在数据库中,当我选择该对象的ID但其他所有内容都是空白时,我可以看到它。不幸的是,Google没有数据库查看器来查看该数据库中的内容。我试图搜索ask但没有运气。 (有one,但它是not working on my computer) 所以,我们走了:

内容

// 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 Course extends Content{

 @Persistent private Video video;
 @Persistent private Document document;
 @Persistent private String notes;
 @Persistent private String summary;

// constructor and getters+setters
    public String toString(){
  return "ID: " + this.getId() + " Title: "+this.getTitle()+", Price: "+this.getPrice()+", No. of Tags: "+this.getTags().size();
 }

}

视频

// 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 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;
}

这是输出:

  

ID:null标题:课程名称 -   1247117389679,价格:99.9,编号   标签:3   ID:agptYWtzaW1zYXBwcgwLEgZDb3Vyc2UYGAwTitle:   课程名称 - 1247117389679,价格:   99.9,标签数量:3 java.lang.NullPointerException at   com.athena.server.entity.Course.toString(Course.java:94)    在   com.athena.server.CourseServiceImpl.testCourse(CourseServiceImpl.java:146)    在   sun.reflect.NativeMethodAccessorImpl.invoke0(母语   方法)at   sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)    在   sun.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)    在   javax.servlet.http.HttpServlet.service(HttpServlet.java:713)    在   javax.servlet.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)

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

为什么会发生这种情况的任何建议?

2 个答案:

答案 0 :(得分:1)

我不确切知道是什么导致了您的错误,但是您可以尝试以下几个步骤来帮助解决问题:

首先,尝试将问题范围缩小到尽可能小的测试用例。你上面发布了很多课程,很可能只有2个或者3个可以复制这个问题。

其次,如果你真的想要确切地看到你的实体在数据存储中的样子,你就必须做这样的事情(或者你可以尝试将你的应用上传到appengine并在那里运行,所以你可以使用他们的DataViewer中):

Query q = pm.newQuery(Course.class);
List<Course> list = (List<Course>) q.execute();
for(Course c: list){
  System.out.println("Course id:" + c.getId());
  System.out.println("Course title:" + c.getTitle());
  //...
}

答案 1 :(得分:0)

我有幸使用无主的一对多关系。基本上你的Lists被一组Key对象取代。

http://code.google.com/appengine/docs/java/datastore/relationships.html