JOD problems regarding detachCopy()

#1

Hi, I am new to JDO and trying to get the PersistenceManager.detachCopy functionality working. I am using ObjectDB 2.8.3

I am

1-saving an object to the db

2-loading that object from the db

3-creating a detached copy

4-closing the connection

5-modifying the detached copy

6-re-opening the connection

7-saving the detached copy

I get an "Attempt to reuse an existing primary key value" error. I have tried enhancing the jar, but did run into some trouble with this as well. Not sure whether enhancement is required?

My code:

@Entity
public class Boat implements Serializable{
    @Id
    private String name;
    private int age;
    
    public Boat(String name, int age){
        this.name=name;
        this.age=age;
    }

   (getters, setters)
}

...

        Boat b=null;
        Boat b_copy=null;
        try {
            Properties properties = new Properties();
            properties.setProperty("javax.jdo.PersistenceManagerFactoryClass", "com.objectdb.jdo.PMF");
            properties.setProperty("javax.jdo.option.ConnectionURL", "objectdbtest2_db.odb");
            PersistenceManagerFactory pmf =JDOHelper.getPersistenceManagerFactory(properties);
            PersistenceManager pm = pmf.getPersistenceManager();            
            try {
                pm.currentTransaction().begin();
                Query q=pm.newQuery(Boat.class);
                Collection res=(Collection)q.execute();
                b=(Boat)res.iterator().next();
                b_copy=pm.detachCopy(b);
                pm.currentTransaction().commit();
            }finally {
                if (pm.currentTransaction().isActive()) pm.currentTransaction().rollback();
                if (!pm.isClosed()) pm.close();
                if (!pmf.isClosed())pmf.close();
            }
        }catch (RuntimeException x) {
            System.err.println("Error: " + x.getMessage());
        }
        
        b_copy.setAge(51); // modification!
        try {
            Properties properties = new Properties();
            properties.setProperty("javax.jdo.PersistenceManagerFactoryClass", "com.objectdb.jdo.PMF");
            properties.setProperty("javax.jdo.option.ConnectionURL", "objectdbtest2_db.odb");
            PersistenceManagerFactory pmf =JDOHelper.getPersistenceManagerFactory(properties);
            PersistenceManager pm = pmf.getPersistenceManager();            
            try {
                pm.currentTransaction().begin();
                pm.makePersistent(b_copy);
                pm.currentTransaction().commit();
            }finally {
                if (pm.currentTransaction().isActive()) pm.currentTransaction().rollback();
                if (!pm.isClosed()) pm.close();
                if (!pmf.isClosed())pmf.close();
            }
        }catch (RuntimeException x) {
            System.err.println("Error: " + x.getMessage());
        }
    }

 

Thanks for any help!

#2

This is an interesting question.

A main difference between JPA and JDO regarding merging detached objects is that JPA has a dedicated method, merge(obj), where JDO uses the same makePersistent(obj) method that is also used to persist new objects. When using makePersistent, ObjectDB has to decide whether it is invoked to persist or merge. Currently ObjectDB can identify it correctly with enhanced classes but not with classes that are not enhanced.

Note that JDO was designed to use with enhancement only, so you may see other small issues if you use JDO without enhancement.

If you use JDO without enhancement, consider replacing makePersistent in that case with an explicit merge:

    ((EntityManager)pm).merge(b_copy);

As you can see, a PersistenceManager can be casted to EntityManager to use JPA from JDO occasionally.

ObjectDB Support
#3

Hi,

this seems to do the trick - thanks!

Reply