Объект хранилища данных Google App Engine не удаляется - PullRequest
2 голосов
/ 21 июля 2011

Я использую хранилище данных Google App Engine для хранения 4-х строковых значений. Строковые значения добавляются в хранилище данных в сервлете:

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");

Я хочу иметь возможность обновлять четыре значения String при каждом запуске сервлета - вот почему я сначала ищу ключ и удаляю его. Я даже использую отдельную транзакцию, чтобы убедиться, что это действительно происходит.

Ключ найден и удален, а затем добавлены значения. Но когда я загружаю файл .jsp, который получает значения, количество «записей» в сущности увеличивается на 1 каждый раз. Я не понимаю, почему запись не удаляется.

Вот код .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() %>

РЕШЕНИЕ

Я не знаю, в чем проблема с кодом в исходном вопросе. Однако я достиг своей цели сохранения строковых значений между сеансами в Google App Engine (GAE) с помощью библиотеки под названием Objectify (http://code.google.com/p/objectify-appengine/)), цель которой - упростить использование хранилища данных в GAE.

Сама библиотека представляет собой просто файл .jar и может быть легко добавлена ​​в проект Java в Eclipse. Я не нашел использование библиотеки настолько простым в использовании ... основная проблема заключается в регистрации класса, который моделирует данные, которые вы хотите сохранить. Регистрация может быть сделана только один раз!

Чтобы зарегистрировать класс только один раз, я добавил в свое веб-приложение прослушиватель, который зарегистрировал класс с помощью инфраструктуры Objectify, а также создал 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
    }
}

.. этот код запускается только один раз при запуске сервера - для этого мне также нужно было изменить web.xml, добавив:

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

Тогда у меня просто была страница .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);
%>

Вот мой класс аккаунта:

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

И последнее ... Я нашел документацию OBjectify очень полезной для понимания хранилища данных GAE независимо от инфраструктуры Objectify

1 Ответ

0 голосов
/ 09 апреля 2013

Для дальнейшего использования, я думаю, ваш исходный пример не удался из-за этой строки:

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

Это на самом деле не создает сущность с primaryKey, но создает сущность сprimaryKey в качестве ключа предка.Он будет автоматически генерироваться при каждом сохранении.

...