문제

Google App Engine 및 JDO를 사용하여 "중첩 된"데이터를 업데이트하는 적절한 방법을 찾는 데 어려움이 있습니다. 나는있다 레시피 그리고 ingredientjdo.

나는 완전히 할 수 있기를 원합니다 재료를 교체하십시오 새로운 재료 목록이있는 주어진 레시피 인스턴스에서. 그런 다음 해당 레시피가 지속되면 이전에 부착 된 성분은 데이터 저장소에서 완전히 삭제되고 새로운 재료는 지속되어 레시피와 관련됩니다.

같은 것 :

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

데이터 저장소에서 반환 된대로 레시피 객체를 직접 업데이트 할 때 제대로 작동합니다. 그러나 내가 복사 Recipejdo는 앞서 언급 한 업데이트를 만들고 새로운 재료를 추가 한 다음 레시피가 데이터 스토어에서 다시 가져 오면 오래된 성분과 함께 반환됩니다. (왜 사본을 귀찮게하는 이유는 무엇입니까? 프론트 엔드에서 GWT를 사용하고 있으므로 JDO 객체를 DTOS에 복사하고 사용자는 프론트 엔드에서 편집 한 다음 백엔드로 전송됩니다. DataStore.)

직접 만든 객체 (ID를 포함한 모든 필드 설정)과 PersistEncemanager가 반환 한 인스턴스에서 작동하는 객체로 다른 결과를 얻는 이유는 무엇입니까? 분명히 JDO의 바이트 코드 향상은 어떻게 든 관련되어 있습니다.

업데이트 된 레시피를 지속하기 전에 오래된 재료를 명시 적으로 삭제하는 것이 좋습니다.

(측면 질문- 다른 사람이 ORM에 좌절하고 우리가 평범한 오래된 RDBM으로 돌아갈 수 있기를 바랍니다. :-)

도움이 되었습니까?

해결책

짧은 대답. 변화 RecipeJDO.setIngredients() 이에:

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

당신이 레시피 jdo를 가져 오면 ingredients 목록은 실제가 아닙니다 ArrayList, 포함 된 요소의 지속성을 처리하는 역동적 인 프록시입니다. 교체해서는 안됩니다.

Persistence Manager가 열려있는 동안 ingredients 목록, 항목 추가 또는 항목을 제거하면 Persistence Manager가 닫히면 (또는 거래가있는 경우 거래가 커밋 된 경우) 변경 사항이 지속됩니다. 거래없이 업데이트를 수행하는 방법은 다음과 같습니다.

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

당신이 결코 수정하지 않는다면 IngredientJDO 물체 (대체하고 읽는 것만), 당신은 그들을 만들고 싶을 수도 있습니다. Serializable JDO 객체 대신 개체. 그렇게하면 재사용 할 수 있습니다. Ingredient GWT RPC 코드의 클래스.

우연히도 Recipe JDO 객체가 아니었고, 당신은 setIngredients() 방법, 그렇지 않으면 누군가가 이것을 할 수 있습니다.

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

다른 팁

나는 같은 문제에 직면하고있다! MakePersistent ()를 호출하고 존재하는 ID/키를 할당하여 기존 엔티티를 업데이트하고 싶습니다! 중첩 된 개체를 제외하고 업데이트는 잘 작동합니다! 중첩 된 물체는 교체 대신 이전 물체에 추가됩니까? 이것이 의도 된 행동인지 또는 이것이 버그인지 모르겠어요? 덮어 쓰기가 새로운 엔티티를 삽입하는 것과 동일한 효과를 갖기를 기대합니다!

기존 엔티티를 먼저 삭제하고 같은 거래에서 새로운 엔티티를 지속하는 것은 어떻습니까? 이것이 작동합니까? 나는 이것을 시도했지만 엔티티를 완전히 삭제 했습니까?! 왜 (삭제 후 바로 플러싱을 시도했지만) 왜 그런지 모르겠습니다!

@namshubwriter,이 게시물을 잡을 것인지 확실하지 않습니다 ... 귀하의 의견과 관련하여

(줄무늬와 JSP를 사용한 경우 레시피 및 성분의 GWT RPC 및 GWT 모델 표현을 피할 수 있습니다)

~이다 줄무늬와 JSP를 사용하지만 같은 문제에 직면합니다. 사용자가 양식을 뒤로 제출하면 Stripes는 내 엔티티 객체를 처음부터 인스턴스화하므로 JDO는 완전히 무지합니다. root 객체에서 makePersistent를 호출 할 때, 이전 버전은 올바르게 덮어 씁니다. 어린이 물체는 추가 ~로 목록u003Cchild> 이전 버전의.

솔루션을 제안 할 수 있다면 (객체 필드를 수동으로 복사하는 것보다 더 낫다) 큰 감사하겠습니다.

(줄무늬가 너무 플러그가 가능하다는 것을보고, 엔티티 객체를 인스턴스화하는 방법을 무시할 수 있는지 궁금합니다 ...)

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top