简体   繁体   English

Google App Engine 数据存储实体未被删除

[英]Google App Engine datastore Entity not being deleted

I am using Google App Engine datastore to store 4 String values.我正在使用 Google App Engine 数据存储来存储 4 个字符串值。 The String vlaues are added to the datastore in a servlet:字符串值被添加到 servlet 中的数据存储区:

DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();

        Entity balances;
        Key primaryKey;
        String table = "MainTable";
        String name = "Values";

        primaryKey = KeyFactory.createKey(table, name);

        Transaction t = datastore.beginTransaction();
            // If the 'table' exists - delete it
        datastore.delete(primaryKey);
            // Really make sure it's deleted/
        t.commit();

        t = datastore.beginTransaction();

            balances = new Entity("Balances", primaryKey);
        updateBalances(balances);
        datastore.put(balances);

            // Save the new data
        t.commit();
        resp.sendRedirect("/balance.jsp");

I want to be able to update the four String values each time the servlet is run - which is why I look for the key first and delete it.我希望能够在每次运行 servlet 时更新四个字符串值——这就是为什么我首先查找密钥并删除它的原因。 I even use a separate transaction to ensure this really happens.我什至使用单独的事务来确保这真的发生。

The key is found and is deleted and then the values are added.找到并删除键,然后添加值。 But when I load a.jsp file which retrieves the values the number of 'records' in the Entity grows by 1 each time.但是,当我加载一个检索值的 .jsp 文件时,实体中的“记录”数每次都会增加 1。 I do not understand why the record is not being deleted.我不明白为什么记录没有被删除。

Here is the.jsp code:这里是.jsp代码:

  <%
        DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();

        Key guestbookKey = KeyFactory.createKey("MainTable", "Values");

        Query query = new Query("Balances", guestbookKey);

        List<Entity> greetings = datastore.prepare(query).asList(FetchOptions.Builder.withLimit(5));
    %>
<!-- This should always be 1, but it gorws each time the servlet is hit.-->
    <%= greetings.size() %>

SOLUTION解决方案

I don't know what the problem was with the code in the original question.我不知道原始问题中的代码有什么问题。 However I achieved my objective of persisting String values across sessions on a Google App Engine (GAE) by using a library called Objectify (http://code.google.com/p/objectify-appengine/) - which aims to simplify the use of the DataStore on GAE.但是,我通过使用名为 Objectify (http://code.google.com/p/objectify-appengine/) 的库实现了在 Google App Engine (GAE) 上的会话中保留字符串值的目标 - 该库旨在简化使用GAE 上的 DataStore。

The library itself is just a.jar file and can be added to a Java project in Eclipse easily.该库本身只是一个.jar 文件,可以轻松添加到 Eclipse 中的 Java 项目中。 I did not find using the library that easy to use...the main problem is registering the class which models the data you wish to save.我没有发现使用易于使用的库...主要问题是注册 class 模型您希望保存的数据。 Registration can only be done once!注册只能完成一次!

To register the class only once I added a listener to my web app which registered the class with the Objectify framework and also created 4 random numbers and saved them:仅在向我的 web 应用程序添加侦听器后才注册 class,该应用程序向 Objectify 框架注册了 class 并创建了 4 个随机数并保存了它们:

public class MyListener implements ServletContextListener {
    public void contextInitialized(ServletContextEvent event) {

            // Register the Account class, only once!
        ObjectifyService.register(Account.class);

        Objectify ofy = ObjectifyService.begin();
        Account balances = null;

            // Create the values we wish to persist.
        balances = new Account(randomNum(), randomNum(), randomNum(),
                randomNum());

            // Actually save the values.
        ofy.put(balances);
        assert balances.id != null;    // id was autogenerated
    }

    public void contextDestroyed(ServletContextEvent event) {
        // App Engine does not currently invoke this method.
    }

    private String randomNum() {
        // Returns random number as a String
    }
}

.. this code is run only once when the server starts - for this to happen I also needed to modify web.xml to add: ..此代码仅在服务器启动时运行一次-为此,我还需要修改 web.xml 以添加:

<listener>
        <listener-class>.MyListener</listener-class>
    </listener>

Then I just had a.jsp page which read the saved values:然后我只有一个读取保存值的.jsp 页面:

<%
Objectify ofy = ObjectifyService.begin();
boolean data = false;
// The value "mykey" was hard coded into my Account class enter code here 
// since I only wanted access to the same data every time.
Account a = ofy.get(Account.class, "mykey");
data = (null!=a);
%>

Here is my Account class:这是我的帐户 class:

import javax.persistence.*;

public class Account
{
    @Id String id = "mykey";
    public String balance1, balance2, balance3, balance4;

    private Account() {}

    public Account(String balance1, String balance2, String balance3, String balance4)
    {
        this.balance1 = balance1;
        this.balance2 = balance2;
        this.balance3 = balance3;
        this.balance4 = balance4;
    }
}

One last thing...I found the OBjectify documentation very helpful in understanding GAE Datastore irrespective of the Objectify framework最后一件事......我发现OBjectify 文档对于理解 GAE 数据存储非常有帮助,无论 Objectify 框架如何

For future reference, I think your original example failed because of this line:为了将来参考,我认为您的原始示例因以下行而失败:

balances = new Entity("Balances", primaryKey);

This doesn't actually create an entity with primaryKey, but it creates an entity with primaryKey as the ancestor key.这实际上并没有创建一个具有primaryKey 的实体,而是创建了一个以primaryKey 作为祖先键的实体。 It will get an automatically generated id every time you store it.每次存储时它都会自动生成一个 id。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM