有时无法使用Cloud Datastore查询(GAE,JDO,Endpoints,Java)检索字符串

时间:2015-02-19 14:10:07

标签: google-app-engine google-cloud-datastore google-cloud-endpoints jdo

我在使用JDO从Google Cloud Datastore检索对象时遇到问题。令人难以置信的是令人沮丧,因为99.5%的时间我的代码完美运行,但有0.5%的时间缺少某些数据,而且我无法找到复制错误的一致步骤。我相当肯定我的问题在于我是如何设置模型的,或者我是如何查询数据存储区的(我怀疑它可能与延迟加载或默认情况有关)取组,但我不确定。

在我解释发生了什么之前,它将有助于理解模型。

以下是我的模型的简化版本:

@PersistenceCapable
@Inheritance(customStrategy = "complete-table") 
public class DataObject {

    @PrimaryKey
    @Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY, defaultFetchGroup="true")
    protected Key theKey;

    @Persistent()
    protected String name;
    //...
}

@PersistenceCapable
public class Class1 extends DataObject{

    @Persistent()
    @Element(dependent="true")
    private List<Class2> listOfClass2 = new ArrayList<Class2>();
    //...   
}

@PersistenceCapable
public class Class2 extends DataObject{

    @Persistent()
    @Element(dependent="true")
    private List<Class3> listOfClass2 = new ArrayList<Class3>();
    //...   
}

@PersistenceCapable
public class Class3 extends DataObject{

    @Persistent()
    private String value;
    //...
}

以下是用于查询数据存储的代码:

public class DataManager {
    public DataObject get(
        User user,
        Class type,
        Long id) throws OAuthRequestException
    {
        PersistenceManager mgr = getPersistenceManager();
       DataObject obj = null;

        try
        {
            obj = mgr.getObjectById(type, id);
            getAllChildren(obj);
        } 
        finally 
        {
            mgr.close();
        }

        if(obj != null)
        {
            return obj; 
        }
        else
        {
            throw new EntityNotFoundException("Entity not found");
        }        
    }

    /** 
     * Returns all of the children of the given object
     * and their children etc. It is intended to 'touch' every object
     * in the tree to accommodate for lazy loading.
     */
    private List<StoredDataObject> getAllChildren(DataObject obj)
    {
        //...
    }
}

问题是,偶尔会出现查询,其中包含所有&#39;名称&#39;给定级别的字段为空。例如,如果我检索Class1的对象,则所有子Class2对象都将具有&#39; name&#39;属性等于&#34;&#34;。数据肯定在数据存储中,因为如果我再次运行查询,它们将被正确填充。我从未见过任何其他属性为空,只有名称字段。有时它出现在Class2级别,有时是Class3,但从不出现Class1(据我所见)。

我的理解是,任何String属性都应该自动包含在默认的fetch组中,但是我可能错过了一个强制名称&#39;每次要检索的属性?

新观察:当发生这种情况时,只要我使用相同的用户凭据运行相同的查询,就会持续发生大约15分钟。这可能与缓存有关吗?

1 个答案:

答案 0 :(得分:-2)

我遇到了一个非常类似的问题。如果这是一个答案,因为我知道我肯定会说,“只需在返回对象之前询问你的记录器值。”

我有一个Swift iOS应用程序连接到我在GAE中运行的java servlet,其中JDO持久性存储到数据存储中(使用GAE插件在Eclipse Kepler中构建和部署)。

由于在生成端点rpc文件时遇到错误,我已根据本网站上的一些帖子对最新的Eclipse GAE插件进行了回归,但其他方面都是默认配置。

我遇到的问题是我有一个表示外键的字段(location.playerId ...虽然没有强制执行此约束,但在任何情况下都不应该引起问题)。我在Swift应用程序中有日志输出,提供以下内容(注意:输出来自INSERT和UPDATE方法调用端点之前,其中“PROXIMAL”行在返回时测试响应对象属性值。返回的位置POJO是处理了响应中的两个案例。):

$$$$$$$$ INSERT LOCATION playerId:6657911736500224

$$$$$$$$ PROXIMAL playerId:nil

$$$$$$$$更新位置playerId:6657911736500224

$$$$$$$$ PROXIMAL playerId:nil

注意传入的playerId值在响应中返回为nil?! INSERT和UPDATE方法是Eclipse生成的默认代码(请参阅下面的PlayerEndpoint的更新列表)。如果我在java servlet中添加一个记录器并输出location.getPlayerId()方法的值,那么我在Swift应用程序中得到如下输出:

$$$$$$$$ INSERT LOCATION playerId:6657911736500224

$$$$$$$$ PROXIMAL playerId:6657911736500224

$$$$$$$$更新位置playerId:6657911736500224

$$$$$$$$ PROXIMAL playerId:6657911736500224

怎么样?!只需通过查询servlet方法中的描述符方法(并且不更改端点代码正在执行的操作),并填充值并通过端点调用返回。这种行为似乎符合可能被解释为某种“延迟加载”的行为,在明确的交互之前不会被解雇。

以上示例使用位置POJO上的playerId字段/方法进行。但是我在Player POJO上有相同的行为,但是使用了player.getDeviceToken()方法。下面是Eclipse中生成的默认代码,作为Player POJO的端点,包含记录器输出。

`    
 public Player updatePlayer(Player player) {
  PersistenceManager mgr = getPersistenceManager();
  try {
    if (!containsPlayer(player)) {
        throw new EntityNotFoundException("Object does not exist");
    }
    player.setUpdated(new Date());
    log.info("(updatePlayer) " + player.getDeviceToken());

    mgr.makePersistent(player);
    log.info("(updatePlayer post persist) " + player.getDeviceToken());
  } finally {
    mgr.close();
  }
  log.info("(updatePlayer prereturn) " + player.getDeviceToken());
  return player;
}

`

(*如果这有助于使Tom的问题可重复并且原因相同):除了将一些值写入记录器之外,任何天才会遇到这个并解决它?!