I'm having issues while trying to update objects with datanucleus (JDO). The problem instead of updating an existing object, it creates new ones along with new embedded data.
This is my 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:
@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):
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?