簡體   English   中英

Datanucleus:嵌入式更新對象創建一個新對象

[英]Datanucleus: embedded update object creates a new one

我在嘗試使用 datanucleus (JDO) 更新對象時遇到問題。 問題不是更新現有對象,而是創建新對象和新嵌入數據。

這是我的 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;
    }

}

這是更新跟蹤器對象的方法(僅跟蹤器的 nombre 屬性):

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 時,不是更新分離的嵌入對象,而是在現有嵌入對象之外創建新的嵌入對象?

更新Tracker實例時,您必須使用與獲取Tracker實例相同的PersistenceManager實例。 此外, PersistenceManager自動檢測對Tracker實例所做的更改,並在適當時將更改提交到數據庫,因此您不必調用makePersistent()方法。

請注意, makePersistent()方法始終插入新記錄。 如果您想做的是 update ,則不得調用 makePersistent()方法。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM