Pregunta

Estoy teniendo problemas para averiguar la forma correcta de actualizar "anidada" datos de uso de Google App Engine y JDO.Tengo un RecipeJDO y un IngredientJDO.

Quiero ser capaces de completamente reemplazar los ingredientes en un determinado receta instancia con una nueva lista de ingredientes.Luego, cuando esa receta es (re)persistió, previamente conectado ingredientes serán eliminados totalmente desde el almacén de datos, y los nuevos que se conservarán y se asocia con la receta.

Algo así como:

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

Esto funciona bien cuando me actualización (separado) receta objetos directamente, tal como se devuelve desde el almacén de datos.Sin embargo, si me copia un RecipeJDO, a continuación, hacer las actualizaciones mencionadas, se termina añadiendo los nuevos ingredientes, que luego son devueltos junto con la edad de los ingredientes cuando la receta es re-bajados desde el almacén de datos.(¿Por qué molestarse con la copia de todo?Estoy usando GWT en la parte delantera, así que me voy a copiar el JDO objetos a organizaciones del narcotráfico, el usuario edita ellos en la parte delantera, y luego son enviados al servidor para actualizar el almacén de datos.)

¿Por qué obtengo resultados diferentes con los objetos que puedo crear con la mano (configuración de todos los campos, incluyendo el id) vs operativo en las instancias devuelto por el PersistenceManager?Obviamente JDO bytecode de la mejora está involucrada de alguna manera.

Estoy mejor simplemente eliminar de forma explícita la edad de los ingredientes antes de persistir actualizado receta de cocina?

(Lado de la pregunta - ¿alguien más se frustran con el ORM y deseamos poder volver a la llanura de edad RDBMS?:-)

¿Fue útil?

Solución

Respuesta corta. Cambio RecipeJDO.setIngredients() a esto:

public void setIngredients(List<IngredientJDO> ingredients) {
  this.ingredients.clear();
  this.ingredients.addAll(ingredients);
}

Al captar la RecipeJDO, la lista ingredients no es un verdadero ArrayList, es un proxy dinámico que maneja la persistencia de los elementos contenidos. Usted no debe reemplazarlo.

Mientras que el gestor de persistencia está abierto, se puede repetir la lista de ingredients, añadir elementos o eliminar elementos, y los cambios se conservará cuando el gestor de persistencia se cierra (o se confirma la transacción, si se encuentra en una transacción) . He aquí cómo se haría la actualización sin una transacción:

public void updateRecipe(String id, List<IngredientDTO> newIngredients) {
  List<IngredientJDO> ingredients = convertIngredientDtosToJdos(newIngredients);
  PersistenceManager pm = PMF.get().getPersistenceManager();
  try {
    RecipeJDO recipe = pm.getObjectById(RecipeJDO.class, id);
    recipe.setIngredients(ingredients);
  } finally {
    pm.close();
  }
}

Si no modifica los objetos IngredientJDO (sólo reemplazarlos y leerlos), es posible que desee hacer que los objetos Serializable en lugar de objetos de JDO. Si lo hace, es posible que pueda volver a utilizar la clase Ingredient en el código GWT RPC.

A propósito, incluso si Recipe no era un objeto de JDO, usted quiere hacer una copia en el método setIngredients(), de lo contrario alguien podría hacer esto:

List<IngredientJDO> ingredients = new ArrayList<IngredientJDO>;
// add items to ingredients
recipe.setIngredients(ingredients);
ingredients.clear(); // Woops! Modifies Recipe!

Otros consejos

Estoy frente al mismo problema! Me gustaría actualizar una entidad existente llamando makePersistent () y la asignación de un identificador de clave existente /! la actualización funciona bien, salvo los objetos anidados! Los objetos anidados se anexan a los ancianos en lugar de ser reemplazado? No sé si este es el comportamiento previsto o si se trata de un error? ESPERO sobrescribir tener el mismo efecto que la inserción de una nueva entidad!

¿Cómo acerca de cómo eliminar primero la antigua entidad y la persistencia de la nueva en la misma transacción? ¿Esto funciona? He intentado esto, pero que dio lugar a la supresión de la entidad completamente ?! No sé por qué (aunque yo he probado el lavado directamente después de borrar)!

@NamshubWriter, no se si vas a coger este post...respecto a su comentario,

(si usted usa Rayas y JSP, puede evitar la GWT RPC y GWT modelo de las representaciones de la Receta y los ingredientes)

Yo am el uso de Rayas y JSP, pero tengo el mismo problema.Cuando el usuario envía el formulario, las Rayas, se crea una instancia de la entidad objetos desde cero, y así JDO es completamente ignorante de ellos.Cuando llamo PersistenceManager.makePersistent en el objeto raíz, la versión anterior está correctamente sobrescriben con una sola excepción, su niño los objetos son anexa a la Lista<child> de la versión anterior.

Si usted podría sugerir alguna solución (mejor que la copia manual de los campos de objeto) les agradecería mucho.

(viendo como las Rayas es tan enchufable, me pregunto si se puede reemplazar cómo se crea una instancia de la entidad objetos...)

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top