|
Another way to model relationships between LDAP entries is to use attribute matching. This means two entries have the same
attribute values. An example of this type of relationship is used by posixGroup and posixAccount object classes were
posixGroup.memberUid points to posicAccount.uid.
We just describe 1-N relationship mapping here and distinguish between unidirectional and bidirectional relationships.
The metadata for 1-1, N-1 and M-N relationship mapping looks identical, the only difference is whether single-valued or
multi-valued attributes are used in LDAP to store the relationships.
We use the following example LDAP tree and Java classes:
dc=example,dc=com public class Department {
| String name;
|-- ou=Departments Set<Employee> employees;
| |-- ou=Sales }
| |-- ou=Engineering
| |-- ... public class Employee {
| String firstName;
|-- ou=Employees String lastName;
| |-- uid=bbunny String fullName;
| |-- uid=dduck String uid;
| |-- uid=sgonzales }
| |-- ...
We have a flat LDAP tree with one container for all the departments and one container for all the employees.
We have two Java classes,
Department
and
Employee
. The
Department
class contains a
Collection of type
Employee
. The
Employee
knows nothing about the
Department
it
belongs to.
There are 2 ways that we can persist this relationship in LDAP because the reference could be stored at the one
or at the other LDAP entry.
One way is to store the reference at the owner object side, in our case at the department entry. This is possible since
LDAP allows multi-valued attributes. The example department entry looks like this:
dn: ou=Sales,ou=Departments,dc=example,dc=com
objectClass: top
objectClass: organizationalUnit
objectClass: extensibleObject
ou: Sales
memberUid: bbunny
memberUid: dduck
Our JDO metadata looks like this:
<jdo>
<package name="com.example">
<class name="Department" table="ou=Departments,dc=example,dc=com" schema="top,organizationalUnit,extensibleObject">
<field name="name" primary-key="true" column="ou" />
<field name="employees" column="memberUid">
<join column="uid" />
</field>
</class>
<class name="Employee" table="ou=Employees,dc=example,dc=com" schema="top,person,organizationalPerson,inetOrgPerson">
<field name="fullName" primary-key="true column="cn" />
<field name="firstName" column="givenName" />
<field name="lastName" column="sn" />
<field name="uid" column="uid" />
</class>
</package>
</jdo>
So we define that the attribute
memberUid
at the department entry should be used to persist the
relationship of field
employees
The important thing here is the
<join>
tag and its
column
.
Firstly it signals DataNucleus to use attribute mapping.
Secondly it specifies the attribute at the other side that should be used for relationship mapping.
In our case, when we establish a relationship between a
Department
and an
Employee
,
the
uid
value of the employee entry is stored in the
memberUid
attribute of the department entry.
Another possible way is to store the reference at the non-owner object side, in our case at the employee entry.
The example employee entry looks like this:
dn: uid=bbunny,ou=Employees,dc=example,dc=com
objectClass: top
objectClass: person
objectClass: organizationalPerson
objectClass: inetOrgPerson
uid: bbunny
cn: Bugs Bunny
givenName: Bugs
sn: Bunny
departmentNumber: Sales
Our JDO metadata looks like this:
<jdo>
<package name="com.example">
<class name="Department" table="ou=Departments,dc=example,dc=com" schema="top,organizationalUnit">
<field name="name" primary-key="true" column="ou" />
<field name="employees">
<element column="departmentNumber" />
<join column="ou" />
</field>
</class>
<class name="Employee" table="ou=Employees,dc=example,dc=com" schema="top,person,organizationalPerson,inetOrgPerson">
<field name="fullName" primary-key="true column="cn" />
<field name="firstName" column="givenName" />
<field name="lastName" column="sn" />
<field name="uid" column="uid" />
</class>
</package>
</jdo>
We need to define the relationship at the department metadata because the employee doesn't know about
the department it belongs to.
With the
<element>
tag we specify that the relationship should be persisted at the other
side and the
column
attribute defines the LDAP attribute to use.
In this case the relationship is persisted in the
departmentNumber
attribute at the employee entry.
The important thing here is the
<join>
tag and its
column
.
As before it signals DataNucleus to use attribute mapping.
Now, as the relation is persisted at the
other
side, it specifies the attribute at
this
side
that should be used for relationship mapping.
In our case, when we establish a relationship between a
Department
and an
Employee
,
the
ou
value of the department entry is stored in the
departmentNumber
attribute of the employee entry.
We use the following example LDAP tree and Java classes:
dc=example,dc=com public class Department {
| String name;
|-- ou=Departments Set<Employee> employees;
| |-- ou=Sales }
| |-- ou=Engineering
| |-- ... public class Employee {
| String firstName;
|-- ou=Employees String lastName;
| |-- uid=bbunny String fullName;
| |-- uid=dduck String uid;
| |-- uid=sgonzales Department department;
| |-- ... }
We have a flat LDAP tree with one container for all the departments and one container for all the employees.
We have two Java classes,
Department
and
Employee
. The
Department
class contains a
Collection of type
Employee
. Now each
Employee
has a reference to its
Department
.
It is possible to persist this relationship on both sides.
dn: uid=bbunny,ou=Employees,dc=example,dc=com
objectClass: top
objectClass: person
objectClass: organizationalPerson
objectClass: inetOrgPerson
uid: bbunny
cn: Bugs Bunny
givenName: Bugs
sn: Bunny
departmentNumber: Sales
<jdo>
<package name="com.example">
<class name="Department" table="ou=Departments,dc=example,dc=com" schema="top,organizationalUnit">
<field name="name" primary-key="true" column="ou" />
<field name="employees" mapped-by="department" />
</class>
<class name="Employee" table="ou=Employees,dc=example,dc=com" schema="top,person,organizationalPerson,inetOrgPerson">
<field name="fullName" primary-key="true column="cn" />
<field name="firstName" column="givenName" />
<field name="lastName" column="sn" />
<field name="uid" column="uid" />
<field name="department" column="departmentNumber">
<join column="ou" />
</field>
</class>
</package>
</jdo>
In this case we store the relation at the employee entry side in a single-valued attribute
departmentNumber
.
With the
<join>
tag and its
column
we specify that the
ou
value of the department entry should be used as join value.
Also note that
employee
field of
Department
is
mapped-by
the
department
field
of the
Employee
.
|
|