繁体   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