# One to Many

A one-to-many relationship exists where a single parent entity holds an array or collection of child entities of a certain type.&#x20;

For example, suppose we have a `Customer` entity and an `Order` entity, and a customer can have multiple orders. The `Customer` entity has a one-to-many relationship with `Order`. The code for these entities looks like this:

```php
class Customer
{
    public int $id;
    public string $name;
    public array $orders = []; // <--One to Many
}

// Note: Each class would of course normally be
// in a separate file.

class Order
{
    public int $id;
    public Customer $customer; // <--Many to one
    //... more properties
}

```

We store the values of the properties for these entities in two database tables, named `customer` and `order:`

| customer |
| -------- |
| `id`     |
| `name`   |

| order                                                            |
| ---------------------------------------------------------------- |
| `id`                                                             |
| `customer_id`  <mark style="color:green;"><-- Foreign key</mark> |
| `...more columns`                                                |

The `order` table contains a foreign key column named `customer_id` which holds the primary key value of the `customer` table. We have no choice over which side owns the relationship - only the `order` table can have a the foreign key, because a customer can have multiple orders, and we can't store multiple foreign keys in a single column.

### Examples

Here are two examples of how to set up the mapping for a one-to-many relationship using attributes or annotations (these examples are all equivalent; you only need to use one type of [mapping provider](/annotations.md), it is up to you which one).&#x20;

As with [one-to-one](/defining-relationships/one-to-one.md#examples), note that the `sourceJoinColumn` attribute (or `@ORM\JoinColumn` annotation if using Doctrine annotations) exists on the owning side (`Order`), and the other side (`Customer`) has a `mappedBy` attribute, telling Objectiphy where to look for the join column. The value of `mappedBy` must be a *property* name, not a column name!

#### Example 1: Minimal Mapping

The following example shows the bare minimum mapping information necessary, on the assumption that the foreign key in the owning table is the primary key of the owned table and that a left join is sufficient. If you are using non-standard columns, or require an inner join, you will need to define them in full as shown in example 2 (note, if using Doctrine annotations, you cannot specify the join type with an annotation).

{% tabs %}
{% tab title="PHP8+ Attributes" %}

```php
use Objectiphy\Objectiphy\Table;
use Objectiphy\Objectiphy\Column;
use Objectiphy\Objectiphy\Relationship;

#[Table(name: 'customer')]
class Customer
{
    #[Column(isPrimaryKey: true)]
    public int $id;
    
    #[Column]
    public string $name;
    
    #[Relationship(
        relationshipType: 'one_to_many',
        childClassName: Order::class,
        mappedBy: 'customer'
    )]
    public array $orders = [];
}

// Note: Each class would of course normally be
// in a separate file.

#[Table(name: 'order')]
class Order
{
    #[Column(isPrimaryKey: true)]
    public int $id;
    
    #[Relationship(
        relationshipType: 'many_to_one',
        childClassName: Customer::class
    )]
    public Customer $customer;
    
    //... more properties
}

```

{% endtab %}

{% tab title="Objectiphy Annotations" %}

```php
use Objectiphy\Objectiphy\Table;
use Objectiphy\Objectiphy\Column;
use Objectiphy\Objectiphy\Relationship;

/**
 * @Table(name="customer")
 */
class Customer
{
    /**
     * @Column(isPrimaryKey=true)
     */ 
    public int $id;
    
    /**
     * @Column
     */
    public string $name;
    
    /**
     * @Relationship(
     *     relationshipType="one_to_many",
     *     childClassName="Order",
     *     mappedBy="customer"
     * )
     */
    public array $orders = [];
}

// Note: Each class would of course normally be
// in a separate file.

/**
 * @Table(name="order")
 */
class Order
{
    /**
     * @Column(isPrimaryKey=true)
     */ 
    public int $id;
    
    /**
     * @Relationship(
     *     relationshipType="many_to_one",
     *     childClassName="Customer"
     * )
     */
    public Customer $customer;
    
    //... more properties
}

```

{% endtab %}

{% tab title="Doctrine Annotations" %}

```php
use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Table(name="customer")
 */
class Customer
{
    /**
     * @ORM\Id
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    public int $id;
    
    /**
     * @ORM\Column()
     */
    public string $name;
    
    /**
     * @ORM\OneToMany(
     *     targetEntity="Order",
     *     mappedBy="customer"
     * )
     */
    public array $orders = [];
}

// Note: Each class would of course normally be
// in a separate file.

/**
 * @ORM\Table(name="order")
 */
class Order
{
    /**
     * @ORM\Id
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    public int $id;
    
    /**
     * @ORM\ManyToOne(targetEntity="Customer")
     */
    public Customer $customer;
    
    //... more properties
}

```

{% endtab %}
{% endtabs %}

#### Example 2: Full Mapping

The following example shows all of the mapping information defined, even though some items could be omitted as Objectiphy can guess some of the mapping if it follows standard conventions. You only need to specify all of the mapping information if you are not joining in a standard way from foreign key to primary key, if your foreign key column name is not suffixed with 'id', or the primary key of the target table, or if you need an inner join (note, if using Doctrine annotations, you cannot specify the join type with an annotation). Example 1, above, shows the exact same mapping as this in an abbreviated format.

{% tabs %}
{% tab title="PHP8+ Attributes" %}

```php
use Objectiphy\Objectiphy\Table;
use Objectiphy\Objectiphy\Column;
use Objectiphy\Objectiphy\Relationship;

#[Table(name: 'customer')]
class Customer
{
    #[Column(isPrimaryKey: true)]
    public int $id;
    
    #[Column]
    public string $name;
    
    #[Relationship(
        relationshipType: 'one_to_many',
        childClassName: Order::class,
        mappedBy: 'customer'
    )]
    public array $orders = [];
}

// Note: Each class would of course normally be
// in a separate file.

 #[Table(name: 'order')]
class Order
{
    #[Column(isPrimaryKey: true)]
    public int $id;
    
     #[Relationship(
         relationshipType: 'many_to_one',
         childClassName: Customer::class,
         sourceJoinColumn: 'customer_id',
         targetJoinColumn: 'id',
         joinType: 'INNER'
     )]
     public Customer $customer;
    
    //... more properties
}

```

{% endtab %}

{% tab title="Objectiphy Annotations" %}

```php
use Objectiphy\Objectiphy\Table;
use Objectiphy\Objectiphy\Column;
use Objectiphy\Objectiphy\Relationship;

/**
 * @Table(name="customer")
 */
class Customer
{
    /**
     * @Column(isPrimaryKey=true)
     */ 
    public int $id;
    
    /**
     * @Column
     */
    public string $name;
    
    /**
     * @Relationship(
     *     relationshipType="one_to_many",
     *     childClassName="Order",
     *     mappedBy="customer"
     * )
     */
    public array $orders = [];
}

// Note: Each class would of course normally be
// in a separate file.

/**
 * @Table(name="order")
 */
class Order
{
    /**
     * @Column(isPrimaryKey=true)
     */ 
    public int $id;
    
    /**
     * @Relationship(
     *     relationshipType="many_to_one",
     *     childClassName="Customer",
     *     sourceJoinColumn="customer_id",
     *     targetJoinColumn="id",
     *     joinType="INNER"
     * )
     */
    public Customer $customer;
    
    //... more properties
}

```

{% endtab %}

{% tab title="Doctrine Annotations" %}

```php
use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Table(name="customer")
 */
class Customer
{
    /**
     * @ORM\Id
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    public int $id;
    
    /**
     * @ORM\Column()
     */
    public string $name;
    
    /**
     * @ORM\OneToMany(
     *     targetEntity="Order",
     *     mappedBy="customer"
     * )
     */
    public array $orders = [];
}

// Note: Each class would of course normally be
// in a separate file.

/**
 * @ORM\Table(name="order")
 */
class Order
{
    /**
     * @ORM\Id
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    public int $id;
    
    /**
     * @ORM\ManyToOne(targetEntity="Customer")
     * @ORM\JoinColumn(
     *     name="customer_id",
     *     referencedColumnName="id"
     * )
     */
    public Customer $customer;
    
    //... more properties
}

```

{% endtab %}
{% endtabs %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.objectiphy.net/defining-relationships/one-to-many.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
