![]() | ![]() |
![]() |
| 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 |
![]() You have a 1-N (one to many) when you have one object of a class that has a Collection of objects of another class. Please note that Collections allow duplicates, and so the persistence process reflects this with the choice of primary keys. There are two ways in which you can represent this in a datastore : Join Table (where a join table is used to provide the relationship mapping between the objects), and Foreign-Key (where a foreign key is placed in the table of the object contained in the Collection. The various possible relationships are described below.
We have 2 sample classes Account and Address. These are related in such a way as Account contains a Collection of objects of type Address, yet each Address knows nothing about the Account objects that it relates to. Like this ![]() There are 2 ways that we can persist this relationship. These are shown below
If you define the Meta-Data for these classes as follows
<entity-mappings>
<entity class="Account">
<table name="ACCOUNT"/>
<attributes>
<id name="id">
<column name="ACCOUNT_ID"/>
</id>
<basic name="firstName">
<column name="FIRSTNAME" length="100"/>
</basic>
<basic name="lastName">
<column name="LASTNAME" length="100"/>
</basic>
<one-to-many name="addresses" target-entity="org.jpox.Address">
<join-table name="ACCOUNT_ADDRESSES">
<join-column name="ACCOUNT_ID_OID"/>
<inverse-join-column name="ADDRESS_ID_EID"/>
</join-table>
</one-to-many>
</attributes>
</entity>
<entity class="Address">
<table name="ADDRESS"/>
<attributes>
<id name="id">
<column name="ADDRESS_ID"/>
</id>
<basic name="city">
<column name="CITY" length="50"/>
</basic>
<basic name="street">
<column name="STREET" length="50"/>
</basic>
</attributes>
</entity>
</entity-mappings>The crucial part is the join-table element on the field element - this signals to JPA to use a join table. This will create 3 tables in the database, one for Address, one for Account, and a join table, as shown below. ![]() The join table is used to link the 2 classes via foreign keys to their primary key. This is useful where you want to retain the independence of one class from the other class. If you wish to fully define the schema table and column names etc, follow these tips
![]() In strict JPA1 you cannot have a 1-N unidirectional relation using a ForeignKey - they must have a JoinTable. Consequently to use this relation as specified below you must specify the property "org.jpox.jpa.oneToManyUniFkRelations" as "true" In this relationship, the Account class has a List of Address objects, yet the Address knows nothing about the Account. In this case we don't have a field in the Address to link back to the Account and so JPOX has to use columns in the datastore representation of the Address class. So we define the MetaData like this
<entity-mappings>
<entity class="Account">
<table name="ACCOUNT"/>
<attributes>
<id name="id">
<column name="ACCOUNT_ID"/>
</id>
<basic name="firstName">
<column name="FIRSTNAME" length="100"/>
</basic>
<basic name="lastName">
<column name="LASTNAME" length="100"/>
</basic>
<one-to-many name="addresses" target-entity="org.jpox.Address">
<join-column name="ACCOUNT_ID"/>
</one-to-many>
</attributes>
</entity>
<entity class="Address">
<table name="ADDRESS"/>
<attributes>
<id name="id">
<column name="ADDRESS_ID"/>
</id>
<basic name="city">
<column name="CITY" length="50"/>
</basic>
<basic name="street">
<column name="STREET" length="50"/>
</basic>
</attributes>
</entity>
</entity-mappings>There will be 2 tables, one for Address, and one for Account. If you wish to specify the names of the column(s) used in the schema for the foreign key in the Address table you should use the join-column element within the field of the collection. ![]() In terms of operation within your classes of assigning the objects in the relationship. You have to take your Account object and add the Address to the Account collection field since the Address knows nothing about the Account. If you wish to fully define the schema table and column names etc, follow these tips
Limitation : Since each Address object can have at most one owner (due to the "Foreign Key") this mode of persistence will not allow duplicate values in the Collection. If you want to allow duplicate Collection entries, then use the "Join Table" variant above.
We have 2 sample classes Account and Address. These are related in such a way as Account contains a Collection of objects of type Address, and each Address has a reference to the Account object that it relates to. Like this ![]() There are 2 ways that we can persist this relationship. These are shown below
If you define the Meta-Data for these classes as follows
<entity-mappings>
<entity class="Account">
<table name="ACCOUNT"/>
<attributes>
<id name="id">
<column name="ACCOUNT_ID"/>
</id>
<basic name="firstName">
<column name="FIRSTNAME" length="100"/>
</basic>
<basic name="lastName">
<column name="LASTNAME" length="100"/>
</basic>
<one-to-many name="addresses" target-entity="org.jpox.Address" mapped-by="account">
<join-table name="ACCOUNT_ADDRESSES">
<join-column name="ACCOUNT_ID_OID"/>
<inverse-join-column name="ADDRESS_ID_EID"/>
</join-table>
</one-to-many>
</attributes>
</entity>
<entity class="Address">
<table name="ADDRESS"/>
<attributes>
<id name="id">
<column name="ADDRESS_ID"/>
</id>
<basic name="city">
<column name="CITY" length="50"/>
</basic>
<basic name="street">
<column name="STREET" length="50"/>
</basic>
<many-to-one name="account">
</many-to-one>
</attributes>
</entity>
</entity-mappings>The crucial part is the join element on the field element - this signals to JPA to use a join table. This will create 3 tables in the database, one for Address, one for Account, and a join table, as shown below. ![]() The join table is used to link the 2 classes via foreign keys to their primary key. This is useful where you want to retain the independence of one class from the other class. If you wish to fully define the schema table and column names etc, follow these tips
Here we have the 2 classes with both knowing about the relationship with the other. If you define the Meta-Data for these classes as follows
<entity-mappings>
<entity class="Account">
<table name="ACCOUNT"/>
<attributes>
<id name="id">
<column name="ACCOUNT_ID"/>
</id>
<basic name="firstName">
<column name="FIRSTNAME" length="100"/>
</basic>
<basic name="lastName">
<column name="LASTNAME" length="100"/>
</basic>
<one-to-many name="addresses" target-entity="org.jpox.Address" mapped-by="account">
<join-column name="ACCOUNT_ID"/>
</one-to-many>
</attributes>
</entity>
<entity class="Address">
<table name="ADDRESS"/>
<attributes>
<id name="id">
<column name="ADDRESS_ID"/>
</id>
<basic name="city">
<column name="CITY" length="50"/>
</basic>
<basic name="street">
<column name="STREET" length="50"/>
</basic>
<many-to-one name="account">
</many-to-one>
</attributes>
</entity>
</entity-mappings>The crucial part is the mapped-by attribute of the field on the "1" side of the relationship. This tells the JPA implementation to look for a field called account on the Address class. This will create 2 tables in the database, one for Address (including an ACCOUNT_ID to link to the ACCOUNT table), and one for Account. Notice the subtle difference to this set-up to that of the Join Table relationship earlier. ![]() If you wish to fully define the schema table and column names etc, follow these tips
Limitation : Since each Address object can have at most one owner (due to the "Foreign Key") this mode of persistence will not allow duplicate values in the Collection. If you want to allow duplicate Collection entries, then use the "Join Table" variant above. |