2011-07-21 42 views
2

我正在使用Google App Engine數據存儲來存儲4個字符串值。絃樂vlaues被添加到數據存儲在一個servlet:Google App Engine數據存儲實體未被刪除

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

我希望能夠更新每個servlet的運行時的四個字符串值 - 這就是爲什麼我期待已久的關鍵第一,並刪除它。我甚至使用單獨的交易來確保這真的發生。

找到並刪除密鑰,然後添加值。但是當我加載一個檢索值的.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() %> 

SOLUTION

我不知道是什麼問題,是在原來的問題的代碼。不過,我通過使用名爲Objectify(http://code.google.com/p/objectify-appengine/)的庫實現了在Google App Engine(GAE)上跨會話持久化字符串值的目標 - 該庫旨在簡化使用GAE上的DataStore。

庫本身只是一個.jar文件,可以很容易地添加到Eclipse中的Java項目中。我沒有找到使用易於使用的庫......主要問題是註冊模擬您希望保存的數據的類。註冊只能做一次!

只登記一次,我添加了一個偵聽器註冊類與對象化框架,也創造了4張隨機數,並保存他們我的web應用程序的類:

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 documentation瞭解GAE數據存儲不論物化框架

+3

在替換它之前不需要刪除實體 - 如果提供相同的密鑰,它將覆蓋現有的實體。看起來您正在更新數據存儲中的單個全局記錄,但是 - 請注意爭用! –

+0

Objectify規則!每個人都說傑夫的文檔是理解數據存儲的最好的東西。 – slugmandrew

回答

0

以供將來參考的非常有幫助的,我覺得你原來的例如失敗,因爲這行:

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

這並不實際創建entit y與primaryKey一起使用,但它創建一個primaryKey作爲祖先關鍵字的實體。每次存儲時都會自動生成一個ID。

相關問題