<hasMany> tag

Description

The hasMany tag defines a relationship where an object has more than one of the child object specified by this tag.  For example, a User might have several addresses.  
 

There are two ways that hasMany relationships can be configured.  The first is just like hasOne relationships except in the opposite direction.  Rather than the parent object having a foreign key to the child object, the child object has the foreign key to the parent.  To clarify, in your database you may have Customer table and an Address table with the following structure:

 

Customer Table

 

Name Type Nullable Default Other
customerId Int No   PK / Identity
username Varchar(50) No    
password Varchar(50) No    
firstName Varchar(50) No    
lastName Varchar(50) No    

dateCreated

DateTime

No

getDate()

 

 

Address Table

 

Name Type Nullable Default Other

addressId

Int

No

 

PK / Identity

customerId

Int

No

 

FK to Customer.customerId

street1

Varchar(50)

No

 

 

street2

Varchar(50)

Yes

 

 

city

Varchar(50)

No

 

 

state

Varchar(50)

No

 

 

zip

Varchar(10)

No

 

 

 

Without any configuration, an instance of a Customer Record will automatically have getters and setters for each of the fields in the table.  However, with a little extra configuration you tell Reactor that your Customer has many Addresses by virtue of the customerId field in both tables.  Here is an example of that configuration:

 

<reactor>
 <objects>
   <object name="Customer">
     <hasMany name="Address">
       <relate from="customerId" to="customerId" />
     </hasMany >
   </object>

   <object name="Address" />

 </objects>
</reactor>

 
Now, when you generate the Customer Record it will not have these additional method:
 
 

Note: All reactor generated methods with return objects lazy load the object.  In other words the Iterator object is not instantiated until you call getAddressIterator().  Additionally these objects are cached.  Calling getAddressIterator() two times will return the same instance of the Address Iterator.

 
The hasMany tag has one child tag, relate, which specify the fields which relate the two objects.  You can nest multiple relate tags to indicate that the relationship between the objects depends on multiple fields.  For example:
 

<reactor>
 <objects>
   <object name="Customer">
     <hasMany name="Address">
       <relate from="customerId" to="customerId" />
       <relate from="fooId" to="fooId" />
     </hasMany>
   </object>

   <object name="Address" />
 </objects>
</reactor>

 
This example shows that the Customer is related by two columns to the Address, addressId and fooId which exist in both tables.  This feature is useful when you have compound foreign keys defined in your database.
 
The other type of hasMany relationships are called linking relationships.  These are used to gain objects which are related via another object.  For example, it's common to have a CustomerAddress table which relates Customers to Addresses.  This type of configuration in databases is frequently called a many to many relationship.  Here's an example database structure:

 

Customer Table

 

Name Type Nullable Default Other
customerId Int No   PK / Identity
username Varchar(50) No    
password Varchar(50) No    
firstName Varchar(50) No    
lastName Varchar(50) No    

dateCreated

DateTime

No

getDate()

 

 

UserAddress Table

 

Name Type Nullable Default Other

userAddressId

Int

No

 

PK / Identity

customerId

Int

No

 

FK to Customer.customerId

addressId

Int

No

 

FK to Address.addressId

 

Address Table

 

Name Type Nullable Default Other

addressId

Int

No

 

PK / Identity

street1

Varchar(50)

No

 

 

street2

Varchar(50)

Yes

 

 

city

Varchar(50)

No

 

 

state

Varchar(50)

No

 

 

zip

Varchar(10)

No

 

 

 

This type of table structure allows for multiple addresses to be related to multiple customer and vice versa.

 

In this type of situation you would define the linking object to have one of both the related objects.  The parent object would have many of the child object via a link though the linking object.  This link is accomplished with the link tag.

 

Here's an example:

 

<reactor>
 <objects>
   <object name="Customer">
     <hasMany name="Address">
       <link name="Customer" />
     </hasMany>
   </object>

   <object name="CustomerAddress">
     <hasOne name="Customer">
       <relate from="customerId" to="customerId" />
     </hasOne>
     <hasOne name="Address">
       <relate from="addressId" to="addressId" />
     </hasOne>
   </object>

   <object name="Address" />
 </objects>
</reactor>

 

Now, when you create a Customer Record the object will have a getAddressIterator() method which will return an Iterator of address objects related to the Customer via the CustomerAddress table.

 

The hasMany tag has an optional alias argument.  When not provided the alias defaults to the value of the name attribute.  The alias argument controls how the methods generated from the relationship are named.  For example, in the example above the Customer object hasMany Address objects. This causes the method name getAddressIterator() to be returned.  If you wanted to rename this method to something else you can provide an alias on the relationship tag.  If you provided an alias of "Location" the generated method would be named getLocatinIterator().
 
Unlike the relate tag, you can express multi-step relationships by providing multiple link tags.

Attributes

Attribute

Required

Description

name

yes

The alias of the related object.

 

Note: If you did not specify an alias for the object that you are relating to, the alias is defaulted to the object's name.

alias

no

The alias to assign to this relationship. When not provided this defaults to the value of the name attribute.

Child tags

Tag

Required

Description

relate

yes (if a link is not provided)

Defines what fields that relate this object to the related object.

link

yes (if a relate is not provided)

Defines the object which links this parent object to its child.

Example

<reactor>
 <objects>
   <object name="Customer">
     <hasone name="Address">
       <relate from="addressId" to="addressId" />
     </hasone>
   </object>

   <object name="Address" />
 </objects>
</reactor>