![]() | ![]() |
![]() |
| Project | Ver 1.1 | Ver 1.2 | JDO | JPA | Guides | Tools |
| 1.2 | Persistence | JDO ORM | JPA ORM | Runtime | JDO Runtime | JPA Runtime | Extensions | Developer |
The power of a Java persistence solution like JPOX is demonstrated when persisting relationships between objects. There are many types of relationships.
When the relation is unidirectional you simply set the related field to refer to the other object. For example we have classes A and B and the class A has a field of type B. So we set it like this A a = new A(); B b = new B(); a.setB(b); // "a" knows about "b" When the relation is bidirectional you have to set both sides of the relation. For example, we have classes A and B and the class A has a collection of elements of type B, and B has a field of type A. So we set it like this A a = new A(); B b1 = new B(); a.addElement(b1); // "a" knows about "b1" b1.setA(a); // "b1" knows about "a" So it is really simple, with only 1 real rule. With a bidirectional relation you must set both sides of the relation
To persist an object with JDO you call the PersistenceManager method makePersistent. The object passed in will be persisted. In addition, all related objects reachable from that object are also persisted (or updated with any new values if they are already persistent). This process is called persistence-by-reachability. The effect of this is that if you have 2 new objects to persist and they are related, then you only need to call makePersistent on one object if it knows about the other object. For example we have classes A and B and class A has a field of type B. To persist them we could do A a = new A(); B b = new B(); a.setB(b); // "a" knows about "b" pm.makePersistent(a); ![]() With JPOX 1.2 you can actually turn off persistence-by-reachability for particular fields, by specifying in the MetaData a JPOX extension tag, as follows
<class name="A">
<field name="b" persistence-modifier="persistent">
<extension vendor-name="jpox" key="cascade-persist" value="false"/>
</field>
...
</class>So with this specification when we call makePersistent() with an object of type A then the field "b" will not be persisted at that time. ![]() With JPOX 1.2 you can actually turn off update-by-reachability for particular fields, by specifying in the MetaData a JPOX extension tag, as follows
<class name="A">
<field name="b" persistence-modifier="persistent">
<extension vendor-name="jpox" key="cascade-update" value="false"/>
</field>
...
</class>So with this specification when we call makePersistent() to update an object of type A then the field "b" will not be updated at that time.
One further complication is that with JDO there is also a process called persistence-by-reachability at commit. When objects are persisted, other objects are persisted with them. If some relations are changed before commit and some of these related objects are no longer required to be persistent then they will not be persisted. For example, using our classes above
A a = new A();
B b = new B();
a.setB(b); // "a" knows about "b"
pm.makePersistent(a);
B b2 = new B();
a.setB(b2); // "a" doesnt know about "b" now. "a" knows about "b2" now.
tx.commit(); // "a" and "b2" will be persisted but "b" wont be since not persisted explicitly and not reachable
With JPOX you can turn off persistence-by-reachability at commit by setting the PersistenceManagerFactory property org.jpox.persistenceByReachabilityAtCommit to false.
As previously mentioned, users should really set both sides of a bidirectional relation. Versions of JPOX from 1.2.0-beta-4 provide a good level of managed relations in that they will attempt to correct any missing information in relations to make both sides consistent. This is defined below For a 1-1 bidirectional relation, at persist you should set one side of the relation and the other side will be set to make it consistent. If the respective sides are set to inconsistent objects then an exception will be thrown at persist. At update of owner/non-owner side the other side will also be updated to make them consistent. For a 1-N bidirectional relation and you only specify the element owner then the collection must be Set-based since JPOX cannot generate indexing information for you in that situation (you must position the elements). At update of element or owner the other side will also be updated to make them consistent. At delete of element the owner collection will also be updated to make them consistent. If you are using a List you MUST set both sides of the relation For an M-N bidirectional relation, at persist you MUST set the one side and the other side will be populated at commit/flush to make them consistent. This management of relations can be turned on/off using a PMF property org.jpox.manageRelationships. If you always set both sides of a relation at persist or update then you could safely turn it off. |