2015-07-03 3 views
-1

У меня возникают проблемы при попытке обновления объектов с помощью datanucleus (JDO). Проблема вместо обновления существующего объекта создает новые, а также новые встроенные данные.Datanucleus: встроенный объект обновления создает новый

Это мой Tracker.java:

@PersistenceCapable(detachable="true") 
@FetchGroup(name="itemsList", members={@Persistent(name="items")}) 
@Version(strategy=VersionStrategy.VERSION_NUMBER) 
public class Tracker implements java.io.Serializable { 

    private static final long serialVersionUID = 2765740961462495537L; 

    @Persistent 
    protected String nombre; 

    @Persistent(embedded="true") 
    protected Item item; 

    @Persistent(embeddedElement="true") 
    @Element(types=Item.class, dependent="true") 
    protected Collection<Item> items; 

    public Tracker() { 
     this.setNombre(""); 
     Item unItem = new Item(); 
     unItem.setNombre("Item principal"); 
     this.setItem(unItem); 
     this.setItems(new HashSet<Item>()); 
    } 

    public String getNombre() { 
     return this.nombre; 
    } 

    public void setNombre(String unNombre) { 
     this.nombre = unNombre; 
    } 

    public Item getItem() { 
     return this.item; 
    } 

    public void setItem(Item unItem) { 
     this.item = unItem; 
    } 

    public Collection<Item> getItems() { 
     return this.items; 
    } 

    public void setItems(Collection<Item> unosItems) { 
     this.items = unosItems; 
    } 

    public void addItem(Item unItem) { 
     if (this.canAddItem(unItem)) this.getItems().add(unItem); 
    } 

    private Collection<String> getItemsNames() { 
     Collection<String> names = new ArrayList<String>(); 
     for (Item i : this.getItems()) names.add(i.getNombre()); 
     return names; 
    } 

    private boolean canAddItem(Item unItem) { 
     if (this.getItemsNames().contains(unItem.getNombre())) return false; 
     return true; 
    } 

} 

Это Item.java:

@PersistenceCapable(detachable="true",embeddedOnly="true") 
@Version(strategy=VersionStrategy.VERSION_NUMBER) 
public class Item implements java.io.Serializable { 

    private static final long serialVersionUID = 2865740961462495537L; 

    @Persistent 
    protected String nombre; 

    public Item() { 
     this.setNombre(""); 
    } 
    public Item(String unNombre) { 
     this.setNombre(unNombre); 
    } 

    public String getNombre(){ 
     return this.nombre; 
    } 

    public void setNombre(String unNombre){ 
     this.nombre = unNombre; 
    } 

} 

Это метод, который обновляет объект Tracker (только атрибут Номбр трекера):

public static void guardarCambiosSobreDetachedTracker(){ 
     Tracker unTracker = getDetachedTracker(); 
     unTracker.setNombre("Nuevo nombre 2"); 
     printer.printTrackerFieldsStatus(unTracker); 
     PersistenceManager pm = PMF.get().getPersistenceManager(); 
     //pm.setCopyOnAttach(false); 
     Transaction tx = pm.currentTransaction(); 
     try { 
      tx.begin(); 
      pm.getFetchPlan().addGroup("itemsList"); 
      pm.getFetchPlan().setFetchSize(3); 

      System.out.println("ANTES DEL PERSIST: " + unTracker); 
      pm.makePersistent(unTracker); 
      tx.commit(); 

      System.out.println("DESPUES: " + unTracker); 
     } finally { 
      if (tx.isActive()) tx.rollback(); 
      pm.close(); 
     } 
     printer.printTrackerFieldsStatus(unTracker); 
    } 

public static Tracker getDetachedTracker(){ 
    PersistenceManager pm = PMF.get().getPersistenceManager(); 
    Transaction tx = pm.currentTransaction(); 
    Tracker detachedTracker = null; 
    try { 
     tx.begin(); 
      Query q = pm.newQuery(Tracker.class); 
      @SuppressWarnings("unchecked") 
      List<Tracker> results = (List<Tracker>) q.execute(); 
      if (results.size() == 1) { 
       pm.getFetchPlan().addGroup("itemsList"); 
       pm.getFetchPlan().setFetchSize(3); 
       detachedTracker = (Tracker)pm.detachCopy(results.get(0)); 
       pm.detachCopyAll(results.get(0).getItems()); 
      } 
     //tx.commit(); 
    } finally { 
     if (tx.isActive()) tx.rollback(); 
     pm.close(); 
    } 

    return detachedTracker; 
} 

Почему при вызове commit вместо обновления встроенных объектов встроены новые кроме существующих внедренных объектов?

+0

и являются ли эти объекты «отдельными»? вызывая JDOHelper.getObjectState, вы можете увидеть состояние. При просмотре журнала вы можете увидеть состояние (а также ЧТО ПРОИСХОДИТ) –

ответ

1

При обновлении экземпляра Tracker, вы должны использовать экземпляр жеPersistenceManager который вы использовали, чтобы получить экземпляр Tracker. Кроме того, PersistenceManager автоматически обнаруживает изменения, внесенные в экземпляр Tracker, и при необходимости изменения привязываются к базе данных, поэтому вам не нужно вызывать метод makePersistent().

Обратите внимание, что метод makePersistent() всегда вставляет новую запись. Если то, что вы хотите сделать, это update, вы не должны называть метод makePersistent().

+1

* makePersistent * не всегда вставляет новую запись. Если переданный объект управляется, он ничего не делает (и обновление обрабатывается автоматически до этого вызова, поскольку вызовы setter перехватываются улучшением байт-кода). Если переданный объект отделяется, он присоединяется к нему. –

+0

Нейл, спасибо за ваш комментарий. –

Смежные вопросы