Я задал вопрос перед тем, как спросить, возможно ли сохранить сложную композицию классов в хранилище данных Google в Google AppEngine с Java, но я не был достаточно ясен и ленив, чтобы опубликовать весь свой класс, но после много часов борьбы я начинаю сдаваться. Так что вот более подробный вопрос с кодом.
Я знаю, что такого рода вещи должны работать нормально, но по неизвестной мне причине это не работает. Проблема в том, что когда я сохраняю свой объект и закрываю соединение с БД, затем открываю его снова, данные в этом объекте остаются пустыми. Объект находится в базе данных, я вижу его, когда выбираю идентификатор этого объекта, но все остальное пусто. К сожалению, Google не имеет средства просмотра базы данных, чтобы увидеть, что находится в этой базе данных. Я попытался найти и попросить , но безуспешно. (есть один , но он не работает на моем компьютере )
Итак, поехали:
Содержание
// 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
}
Tag
// 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: nullTitle: Название курса -
1247117389679, Цена: 99,9, №
Теги: 3
ID: agptYWtzaW1zYXBwcgwLEgZDb3Vyc2UYGAwTitle:
Название курса - 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 (Native
Метод) в
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)
Я знаю, что эта ошибка означает, что строка пуста. Но запись в базе данных. И это должно сохраняться. Почему данные пустые ???
Есть предложения, почему это происходит со мной?