【问题标题】:GWT + GAE datastore Key and Text Java ErrorGWT + GAE 数据存储区密钥和文本 Java 错误
【发布时间】:2011-08-29 07:30:00
【问题描述】:

我想创建一个将记录保存和检索到 GAE 服务器的应用程序。我按照教程“部署到 Google App Engine”http://code.google.com/webtoolkit/doc/latest/tutorial/appengine.html 开始操作。

我的 StockWatcher 应用程序现在正在运行,但在我的应用程序中我需要存储一个可能很大 (>10KB) 的字符串。我读到我不能使用 Java String 类型来存储大字符串,而需要使用 Text 数据类型。

我认为文本是指:com.google.appengine.api.datastore.Text,但最好确认这是正确的。 ???

无论如何,我无法让 Text 工作。经过一些研究,似乎 Key 和 Text 类型都只能在服务器代码中使用,而不能在客户端代码中使用。这似乎是因为这些类的源代码不可用,而 GWT 需要源代码才能在客户端计算机上创建 JavaScript 代码。至少我目前关于为什么会出现以下错误的工作假设:

21:52:52.823 [ERROR] [myapp] Line 15: The import com.google.appengine.api.datastore cannot be resolved
21:52:52.951 [ERROR] [myapp] Line 103: Key cannot be resolved to a type
21:52:53.011 [ERROR] [myapp] Line 106: Text cannot be resolved to a type

我在共享文件夹的类中使用以下字段。

共享/MyDataRecord

@PrimaryKey
@Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
private Key id;

@Persistent
private Text description;

共享文件夹中的 MyDataRecord 类,因为我想用一个 get 方法返回所有字段,而不是多个单独的字段 get 方法。这是我在 server/DataServiceImpl.java 类中使用 MyDataRecord 类的方法

public class DataServiceImpl extends RemoteServiceServlet implements DataService
{
...
  @Override
  public MyDataRecord getDataRecord() throws NotLoggedInException
  {
    ...

我看到一些已发布的解决方案建议使用非标准的第 3 方库,例如 http://www.resmarksystems.com/code/。我无法安装这个,但即使可以,我更喜欢不同的解决方案。存储文本必须是一项常见的任务,我更愿意使用被认为是标准解决方案的方法来解决这个问题。

我可以更改我的代码以在多个 get 方法中返回每个字段,而不是单个返回 MyDataRecord 实例。然而,即使这样有效,随着时间的推移,这将是更多的工作并且更难以维护。但是,如果这是通常所期望的,那么这就是我要做的。

我想使用 GWT 和 GAE 认为的最佳做法来解决这个问题。一个简单的例子或教程会有很长的路要走,但我找不到。

是否有示例程序/教程展示了 GWT 认为存储和检索大字符串的最佳实践?

我是 GWT 和 GAE(以及 Web 开发)的新手,请在任何回复中考虑这一点,谢谢。

请不要打蛇

【问题讨论】:

  • 举个例子是回答这个问题的最简单方法。

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


【解决方案1】:

可序列化的 POJO。注意描述的 NotPersistent 注解

package com.my.project.shared;

@PersistenceCapable(identityType=IdentityType.APPLICATION,detachable="true")
public class MyParent implements Serializable {

    @PrimaryKey
    @Persistent(valueStrategy=IdGeneratorStrategy.IDENTITY)
    private Long id;
    @NotPersistent //Note the NotPersistent annotation. GAE won't persist this value in big table
    private String description;

}

第二个 POJO。注意包裹

package com.my.project.server;

@PersistenceCapable(identityType=IdentityType.APPLICATION,detachable="true")
public class MyChild implements Serializable{//Not really required to implement Serializable

    @PrimaryKey
    @Persistent(valueStrategy=IdGeneratorStrategy.IDENTITY)
    private Long id;
    @Persistent
    private Long parentID;//Reference to the MyParent
    @Persistent
    private Text description;//The actual value of the description variable.
}

注意映射到子级的父级 ID。在检索时,您需要确定哪个孩子属于哪个父母。 在伪代码中 1)从数据库加载父级 2)识别这个父母的孩子,并加载它 3) 转换 child.description->parent.description 4) 现在你有一个完全构造的可序列化的父 POJO。发送到 UI

只需在从 UI 回到 GAE 的过程中颠倒过程即可。

【讨论】:

  • 谢谢。这很清楚。在查看您的建议后,我可能会看到 2 种可能的解决方案,具体取决于我是否理解您的建议。两种解决方案都需要将类分成 2 个类,但方式不同。
  • 一种方法,通过将所有只能在服务器上使用的数据成员(如 Text 和 Key)放在一个类中来拆分类。在另一个类中放置所有可以在客户端和服务器上共享的数据成员。
  • 另一种方法是通过复制每个类中的所有数据成员来拆分类。就像第一种方式一样,在共享类中使用 Long 存储 Key 和 String 存储 Text。共享类将是 POJO,因为它不会被持久化(无 @Persistent 数据)。您将需要能够在每个类之间进行转换。定义的客户端接口(DataService.java 和 DataServiceAsync.java)将只使用共享类。服务器的类(DataServiceImpl.java)实现将在读取和写入数据库时​​使用用户定义的转换。
  • 如果没有完整的例子,我可能会误解你在说什么,所以也许我还是不明白。由于我没有使用 GAE 的经验,因此我可能缺少其他注意事项。另外,由于我还没有尝试过任何一种解决方案,可能会有我无法预见的问题。我认为 2 全类解决方案会更好,因为这意味着每个类实例只在数据库中保存一条记录。
【解决方案2】:

1) 在您的可序列化 POJO 私有字符串描述中定义一个 NotPersistent 字段 2) 在服务器端上定义一个新的 POJO,它将有私有文本描述 3) 当您持久化/加载原始 POJO 时,检索新的 POJO 并从文本描述中填充字符串描述

【讨论】:

  • 那么做两节课?一种实现了 java.io.Serializable 接口并且是 POJO。另一个具有@Persistent 私有文本描述的类;并编写在所有字段之间来回转换的代码?维护 2 个类似乎需要做很多工作,但如果这是预期的,那就是我要做的。谢谢。
  • 没有。第二类只有一个 ID,它映射到第一类的 UID 和文本描述。无需拥有第一个 POJO 的完整副本。只是抽象文本
  • 好吧,我不明白你在说什么。你能指出一个示例程序/教程来说明你在说什么吗?
猜你喜欢
  • 1970-01-01
  • 2012-08-10
  • 1970-01-01
  • 2012-10-11
  • 1970-01-01
  • 2011-12-15
  • 1970-01-01
  • 1970-01-01
  • 2011-09-23
相关资源
最近更新 更多