2011-07-21 4 views
2

J'utilise la banque de données Google App Engine pour stocker 4 valeurs de chaîne. Les vlaues de chaîne sont ajoutés au magasin de données dans un servlet:Base de données Google App Engine Entité non supprimée

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

Je veux être en mesure de mettre à jour les quatre valeurs de chaîne chaque fois que le servlet est exécuté - ce qui est la raison pour laquelle je cherche la première clé et le supprimer. J'utilise même une transaction distincte pour m'assurer que cela se produise vraiment.

La clé est trouvée et est supprimée, puis les valeurs sont ajoutées. Mais lorsque je charge un fichier .jsp qui récupère les valeurs, le nombre d'enregistrements dans l'entité augmente de 1 à chaque fois. Je ne comprends pas pourquoi l'enregistrement n'est pas supprimé.

Voici le 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

Je ne sais pas quel était le problème avec le code dans la question initiale. Cependant, j'ai atteint mon objectif de conserver les valeurs String sur plusieurs sessions sur un moteur Google App Engine (GAE) en utilisant une bibliothèque appelée Objectify (http://code.google.com/p/objectify-appengine/), qui vise à simplifier l'utilisation. du DataStore sur GAE.

La bibliothèque elle-même est juste un fichier .jar et peut être facilement ajoutée à un projet Java dans Eclipse. Je n'ai pas trouvé que l'utilisation de la bibliothèque était facile à utiliser ... le problème principal est l'enregistrement de la classe qui modélise les données que vous souhaitez enregistrer. L'inscription ne peut être faite qu'une seule fois!

Pour enregistrer la classe une seule fois j'ai ajouté un auditeur à mon application web qui a enregistré la classe avec le cadre Objectify et a également créé 4 nombres aléatoires et les a sauvés

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

.. ce code est exécuté seulement une fois lorsque le serveur démarre - pour cela aussi que je devais modifier web.xml ajouter:

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

Je viens d'avoir une page .jsp qui lit les valeurs enregistrées:

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

Voici ma classe de compte:

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

Une dernière chose ... j'ai trouvé le OBjectify documentation très utile pour comprendre GAE Datastore quel que soit le cadre

+3

Il n'est pas nécessaire de supprimer une entité avant de la remplacer. Si vous fournissez la même clé, elle écrasera l'entité existante. Il semble toutefois que vous mettiez à jour un seul enregistrement global dans votre banque de données. Attention aux conflits! –

+0

Objectify règles! Tout le monde dit que les documents de Jeff sont la meilleure chose qu'ils ont lu en termes de compréhension de la banque de données. – slugmandrew

Répondre

0

Objectify Pour référence ultérieure, je pense que votre original exemple a échoué en raison de cette ligne:

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

cela ne crée pas une entit y avec primaryKey, mais il crée une entité avec primaryKey comme clé ancêtre. Il obtiendra un identifiant généré automatiquement chaque fois que vous le stockez.

Questions connexes