Je n'arrive pas à trouver la bonne façon de mettre à jour les données "imbriquées" à l'aide de Google App Engine et JDO. J'ai un RecipeJDO et un IngredientJDO.Mise à jour des objets "imbriqués" avec JDO sur Google App Engine
Je veux être complètement remplacer les ingrédients dans une instance de recette donnée avec une nouvelle liste d'ingrédients. Ensuite, lorsque cette recette est (re) conservée, tous les ingrédients précédemment attachés seront totalement supprimés du magasin de données, et les nouveaux seront conservés et associés à la recette.
Quelque chose comme:
// retrieve from GAE datastore
RecipeJDO recipe = getRecipeById();
// fetch new ingredients from the user
List<IngredientJDO> newIngredients = getNewIngredients();
recipe.setIngredients(newIngredients);
// update the recipe w/ new ingredients
saveUpdatedRecipe(recipe);
Cela fonctionne bien quand je mets à jour (détaché) recette objets directement, retournée par le magasin de données. Toutefois, si je recopie un RecipeJDO, puis faire les mises à jour mentionnées ci-dessus, il finit par ajouter les nouveaux ingrédients, qui sont ensuite retournés avec les anciens ingrédients lorsque la recette est ensuite récupérée à partir du magasin de données. (Pourquoi s'embêter avec la copie?) J'utilise GWT sur le frontal, donc je copie les objets JDO vers les DTO, l'utilisateur les édite sur le frontal, puis ils sont envoyés au backend pour mettre à jour le banque de données.)
Pourquoi est-ce que j'obtiens des résultats différents avec les objets que je crée manuellement (en définissant tous les champs, y compris l'ID) vs en opérant sur les instances renvoyées par PersistenceManager? Évidemment L'amélioration de bytecode de JDO est impliquée en quelque sorte. Est-il préférable de supprimer explicitement les vieux ingrédients avant de continuer la recette mise à jour de ?
(question- côté que quelqu'un d'autre se sentent frustrés avec ORM et que vous souhaitez que nous pourrions revenir à bon vieux SGBDR? :-)
Désolé, cela ne résout pas le problème. Je ne l'ai pas très bien articulé. Quand j'obtiens les recettes (non-JDO) de GWT, je crée de nouveaux objets RecipeJDO (j'appelle littéralement "new RecipeJDO()"), copiez tous les champs, et ensuite faites pm.makePersistent() dessus. C'est la création via "new" qui cause le problème. Si je prends à la place le RecipeJDO à partir du datastore, puis que je copie les champs, tout va bien. Je suppose que la solution est de récupérer l'ancien RecipeJDO à partir du magasin de données, de copier les champs dans cet objet, puis de mettre à jour cet objet. SQL a l'air mieux tout le temps. ;-) –
Si vous mettez à jour une recette existante, ne créez pas un nouvel objet RecipeJDO. Créer un nouvel objet ReceipeJDO et appeler makePersistent(), c'est comme faire un SQL INSERT. Les données étaient déjà insérées lors de la création de la recette. Après cela, vous devriez le mettre à jour. – NamshubWriter
Oui, mais je mets l'identifiant de RecipeJDO à l'identifiant d'une recette existante dans le datastore, donc cela devrait fonctionner comme une mise à jour. Et c'est le cas, sauf que les (nouveaux) ingrédients sont ajoutés à la liste des ingrédients existants, plutôt que de les remplacer. Il semble que je devrais peut-être récupérer le RecipeJDO à partir de PersistenceManager, mettre à jour ses champs, supprimer tous les ingrédients existants (en utilisant sa liste d'origine), puis ajouter les nouveaux ingrédients, puis recommencer. Bien que cela fasse probablement ce dont j'ai besoin, il me semble qu'il y a énormément de travail qui en quelque sorte nie l'utilité d'un ORM en premier lieu. –