JPOX
JPOX
 Project  |  Ver 1.1  |  Ver 1.2  |  JDO  |  JPA  |  Guides  |  Tools
1.1 | Preparation | O/R Mapping | Runtime | Extensions | Developer
O/R Mapping
Relationships
Relationships

The power of a Java persistence solution like JPOX is demonstrated when persisting relationships between objects. There are many types of relationships.

  • 1-1 relationships - this is where you have an object A relates to a second object B. The relation can be unidirectional where A knows about B, but B doesnt know about A. The relation can be bidirectional where A knows about B and B knows about A.
  • 1-N relationships - this is where you have an object A that has a collection of other objects of type B. The relation can be unidirectional where A knows about the objects B but the Bs dont know about A. The relation can be bidirectional where A knows about the objects B and the Bs know about A
  • N-1 relationships - this is where you have an object B1 that relates to an object A, and an object B2 that relates to A also etc. The relation can be unidirectional where the A doesnt know about the Bs. The relation can be bidirectional where the A has a collection of the Bs. [i.e a 1-N relationship but from the point of view of the element]
  • M-N relationships - this is where you have objects of type A that have a collection of objects of type B and the objects of type B also have a collection of objects of type A. The relation is always bidirectional by definition
Assigning 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



Persisting Relationships

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);

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.

Managed Relationships

As we have mentioned above, it is for the user to set both sides of a bidirectional relation. If they dont and object A knows about B, but B doesnt know about A then what is the persistence solution to do ? It doesnt know which side of the relation is correct. JDO doesnt define the behaviour currently for this situation. JPOX currently just tries to persist the relation information as presented. If the two sides of a bidirectional relation are inconsistent then the persistence results are undefined.