简体   繁体   English

Datanucleus:嵌入式更新对象创建一个新对象

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

I'm having issues while trying to update objects with datanucleus (JDO).我在尝试使用 datanucleus (JDO) 更新对象时遇到问题。 The problem instead of updating an existing object, it creates new ones along with new embedded data.问题不是更新现有对象,而是创建新对象和新嵌入数据。

This is my Tracker.java:这是我的 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;
    }   

}

This is Item.java:这是 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;
    }

}

This is the method that updates a Tracker object (only tracker's nombre attribute):这是更新跟踪器对象的方法(仅跟踪器的 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;
}

Why is it that when calling commit, instead of updating dettached embedded objects, it creates new ones besides existing embedded objects?为什么在调用 commit 时,不是更新分离的嵌入对象,而是在现有嵌入对象之外创建新的嵌入对象?

When you update the Tracker instance, you have to use the same PersistenceManager instance which you used to get the Tracker instance.更新Tracker实例时,您必须使用与获取Tracker实例相同的PersistenceManager实例。 In addition, PersistenceManager automatically detects changes made on the Tracker instance and the changes are committed to the database when appropriate, so you don't have to call makePersistent() method.此外, PersistenceManager自动检测对Tracker实例所做的更改,并在适当时将更改提交到数据库,因此您不必调用makePersistent()方法。

Note that makePersistent() method always inserts a new record. 请注意, makePersistent()方法始终插入新记录。 If what you want to do is update , you must not call makePersistent() method. 如果您想做的是 update ,则不得调用 makePersistent()方法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM