3.11 Object Identity
One of the key concepts defined in JDO is that of object identity, although in most cases a developer is not even aware that it exists. Every persistent object has a JDO object identity. This identity associates the in-memory Java object with its representation in the underlying datastore. JDO ensures that there is only one in-memory representation of a given persistent object for a given PersistenceManager. This is known as "uniquing." Uniquing ensures that no matter how many times a persistent object is found, it has only one in-memory representation. All references to the same persistent object within the scope of the same PersistenceManager instance reference the same in-memory object.
The following code snippet taken from UniquingExample.java shows uniquing at work. It creates a new Author instance, begins a new transaction, and finds the Author again using a query. The two references are then compared to validate that they both refer to the same in-memory object:
tx.begin(); Author author1 = new Author("Keiron McCammon"); pm.makePersistent(author1); tx.commit(); tx.begin(); Query query = pm.newQuery(Author.class, "name == \"Keiron McCammon\""); Collection result = (Collection) query.execute(); Author author2 = (Author) result.iterator().next(); tx.commit(); if (author1 == author2) System.out.println("There is only one object in memory");
The output would be as follows:
There is only one object in memory
However, because it is possible to create multiple PersistenceManager instances within a JVM, it is possible that a persistent object may have multiple in-memory representations at any given timeat most, one per PersistenceManager. Each would have the same JDO object identity, but would be a different in-memory Java object. To determine whether two in-memory objects represent the same persistent object, their JDO object identities can be compared. The JDOHelper class provides a method to get the JDO object identity of an object:
static Object getObjectId(Object pc)
The returned object can be compared with another using the equals() method to determine whether two in-memory objects represent the same persistent object in the datastore.
The following code snippet taken from ObjectIdentityExample.java creates an Author using one PersistenceManager, and then using a different PersistenceManager, it finds the Author again. The two references are compared to validate that they refer to different in-memory objects. The JDO identities are then compared to validate that they do, however, represent the same persistent object:
tx1.begin(); Author author1 = new Author("Keiron McCammon"); pm1.makePersistent(author1); tx1.commit(); PersistenceManager pm2 = pmf.getPersistenceManager(); Transaction tx2 = pm2.currentTransaction(); tx2.begin(); Query query = pm2.newQuery(Author.class, "name==\"Keiron McCammon\""); Collection result = (Collection) query.execute(); Author author2 = (Author) result.iterator().next(); tx2.commit(); if (author1 != author2) System.out.println( "There are multiple objects in memory"); Object author1Id = JDOHelper.getObjectId(author1); Object author2Id = JDOHelper.getObjectId(author2); if (author1Id.equals(author2Id)) System.out.println("But they represent the same Author");
The output would be as follows:
There are multiple objects in memory But they represent the same Author
JDO actually defines three types of object identity for persistent objects: datastore identity, application identity, and non-durable identity.