One to one relationship using Zend 3 and Doctrine 2

Using Doctrine 2 annotations in a Zend project requires us to design our database model at first then we are integrating ou entities which themselves are instantiated within services.

Today we are going to implement a simple example of using a One to one relationship using Doctrine and Zend 3.

Example of a One2one relationship using Doctrine 2 and Zend 3

One 2 One relationship

We will take 2 simple tables as an example :

  1. a person table with name and id
  2. the identification number with its number and id

The second table refers to the first one using a foreign key : personId (or person_id inside the table in its Database form).

The relationship between our tables

To be clear, we will state the following assumptions :

  • One person has 1 identification number only
  • One identification number belongs to 1 person only

We have a clear 1 to 1 bidirectional relationship here. For more information, you may refer to the doctrine 2 documentation. For the sake of this tutorial we will assume that we have an unidirectional relationship between our entities, in other words, we don’t need to map the person with the identification number.

Let’s now build our entities where table models are defined.

The person entity

namespace MyModule\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * This class represents a single person
 * @ORM\Entity
 * @ORM\Table(name="person")
 */
class Person
{
	/**
	 * @ORM\Id
	 * @ORM\GeneratedValue
	 * @ORM\Column(name="id",type="integer")
	 */
	protected $id;
	
	/**
	 * @ORM\Column(name="name")
	 */
	protected $name;
		
	// Returns ID of this person.
	public function getId()
	{
		return $this->id;
	}
	
	// Returns name
	public function getName()
	{
		return $this->name;
	}
	
	// Sets name of person
	public function setName($name)
	{
		$this->name = $name;
	}
	
}

Add now your identification number entity as follow :

namespace MyModule\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * This class represents a single identification number
 * @ORM\Entity
 * @ORM\Table(name="id_number")
 */
class IdNumber
{
	/**
	 * @ORM\Id
	 * @ORM\GeneratedValue
	 * @ORM\Column(name="id",type="integer")
	 */
	protected $id;
	
	/**
	 * @ORM\Column(name="number",type="string")
	 */
	protected $number;
	
	/**
	 * One number entry belongs to One person
	 * @ORM\OneToOne(targetEntity="\MyModule\Entity\Person")
	 * @ORM\JoinColumn(name="person", referencedColumnName="id")
	 */
	protected $person;

	
	// Returns ID of this number.
	public function getId()
	{
		return $this->id;
	}
	
	// Returns id number
	public function getNumber()
	{
		return $this->number;
	}
	
	// Sets number of person
	public function setNumber($number)
	{
		$this->number = $number;
	}
	
	
	/**
	 * Returns ID of person for this vat id number.
	 * @param person
	 */
	public function getPerson()
	{
		return $this->person;
	}
	
	/**
	 * Adds a new person matching this number
	 * @param 
	 */
	public function setPerson($id)
	{
		$this->person = $id;
	}

	
}

As the above code is straightforward, we won’t comment about it but rather stay focused on our matter while dealing with entries in the database using our services.

For instance if you plan on adding a new identification number matching an existing person using the following command :

// Create new number entity.
$number = new IdNumber();
$number->setNumber($data['number']);
$number->setPerson($data['person']);

// Add the entity to the entity manager.
$this->entityManager->persist($vat);

// Apply changes to database.
$this->entityManager->flush();

The $data array is filled after a form submission, for more details on using forms in Zend, please refer to the signup tutorial.

Depending on the content of the $data[‘person] parameter, you might trigger the following error :

 

Expected value of type "MyModule\Entity\Person" for association field "MyModule\Entity\IdNumber#$person", got "integer" instead.

If you read carefully, the hint is pretty obvious, you’ve taken the id of the entity and not the entity itself to map the person to the identification number. In other words : make sure you add an id_number entry with the person entity as a parameter.

For example, if you have an integer into $data[‘person’], then change the content as follow using your service manager :

$person  = $this->entityManager->getRepository(Person::class)
->findOneBy(array('id' => $data['person']));

Then use that entity to add the new entry in the database :

$number->setPerson($person);

Ok ! now you are good to go with this type of One2One relationship using Zend 3 and Doctrine 2.

I hope you have a better understanding of implementing the model through your projects. Do not hesitate if you have any questions or concerns.

Leave a Reply

Want more information?

Related links will be displayed here in this section for you to pick up another good spot to get more details about Web marketing and Search Engine Optimization. There will be some sites which we selected to ease the work of any webmaster or/and web marketer on the Internet.

%d bloggers like this: