CodeSamplez.com

Programming, Web development, Cloud Technologies

  • Facebook
  • Google+
  • RSS
  • Twitter
  • Home
  • Featured
    • C# Tutorials
      • LinQ Tutorials
      • Facebook C# API Tutorials
    • PHP Tutorials
      • CodeIgniter Tutorials
    • Amazon AWS Tutorials
  • Categories
    • Programming
    • Development
    • Database
    • Web Server
    • Source Control
    • Management
    • Project
  • About
  • Write
  • Contact
Home Database Doctrine Relationship Management Between Entities

Doctrine Relationship Management Between Entities

Rana Ahsan May 5, 2013 3 Comments


 Doctrine Relationship Management Between Entities    

As we are using Doctrine ORM for easing our database layer programming, it’s very important to understand how to establish the doctrine relationship between entities and do it in proper way to build a robust relational database design. Here by the term ‘relationship’, I meant the x-to-x relations, which can take form of one to one,one to many (many to one) or many to many relationship etc. I am assuming you have started using doctrine and have some basic idea how to declare and perform Doctrine CRUD operations at least.

Ways To Establish Relationship:

Well, It is always mandatory that, you need to have a complete synchronization between your entities’ annotation/property declaration and your database structure. You can though can do that manually, its time-consuming and have possibility of buggy implementation. Sometimes, you will may find yourself messing around, but can’t exactly catch the reason of a raised issue. waste of time, mental torture.
doctrine relational table
So, it is strongly recommended that you implement on only one side and use php script or CLI tool for transformation between doctrine entities and database.

I usually like to establish the doctrine relationship in entities and then update the database schema and will show this way here. There is some specific benefits as well, that you will know later on this article. Keep reading on.

One To One Relationship:

Lets assume, we have two entity named ‘Users’ And ‘Profiles’. It can be a good example of one to one relationship. As every user has only one profile and each profile can be associated with only one user. Now, so said, as a rule of thumb, we will have to add an identity foreign key(as per database language) to one table that linked to the another table.

Now which table need to contain and link to another? To decide this, first think, which entity comes first and which is optional. The secondary entity need to have a link to its primary entity. In this example scenario, from general knowledge, we know, first we need to have a user in our system who can later create a profile. So, user is primary here and profile is secondary. So, in profile entity, we will have property/database column definition like as follows:

/**
 * UserProfile
 *
 * @Table(name="user_profile")
 * @Entity
 */
class UserProfile
{
    /**
     * @var integer $id
     *
     * @Column(name="id", type="integer", nullable=false)
     * @Id
     * @GeneratedValue(strategy="IDENTITY")
     */
    private $id;

    //other declarations.....

    /**
     * @var Users
     *
     * @OneToOne(targetEntity="Users")
     * @JoinColumns({
     *   @JoinColumn(name="user_id", referencedColumnName="id", onDelete="CASCADE")
     * })
     */
    private $user;

    /**
     * Get id
     *
     * @return integer 
     */
    public function getId()
    {
        return $this->id;
    }

    //other getter/setter declarations.....

    /**
     * Set user
     *
     * @param Users $user
     * @return UserProfile
     */
    public function setUser(\Users $user = null)
    {
        $this->user = $user;
        return $this;
    }

    /**
     * Get user
     *
     * @return Users 
     */
    public function getUser()
    {
        return $this->user;
    }
}

As you can see above, this declaration will create a foreign key on ‘profiles’ and link to ‘users’ table’s ‘id’ column, Now when we create a new profile, we can set the corresponding user with use of setter property and we should be fine. Also, if you check your database, you will find that, a new unique key is also generated on ‘user_id’ column, which is because of the ‘OneToOne’ relation declaration. See the below example of saving a Profile entity:

$id = 1;
$user = $em->getRepository("Users")->find($id);

$profile = new UserProfile();
$profile->setFirstName("test first name");
$profile->setLastName("test last name");
$profile->setUser($user);
$em->persist($profile);
$em->flush();

One To Many Doctrine Relationship:

Lets say, your web application is providing specific access level permission to its users. a single role can be assigned to as many users, but each user are associated to only a single role at a time. This is very good example of one to many(role to user) or many to one(users to role). And here its easy to guess that, we will need to add a property in ‘user’ entity which link to ‘role’ entity’s ‘id’ property as below:

/**
 * Users
 *
 * @Table(name="users")
 * @Entity
 */
class Users
{
    /**
     * @var integer $id
     *
     * @Column(name="id", type="integer", nullable=false)
     * @Id
     * @GeneratedValue(strategy="IDENTITY")
     */
    private $id;

    //other declarations.....

    /**
     * @var Roles
     *
     * @ManyToOne(targetEntity="Roles")
     * @JoinColumns({
     *   @JoinColumn(name="role_id", referencedColumnName="id")
     * })
     */
    private $role;

    //other getter/setter declarations.....

    /**
     * Set role
     *
     * @param Roles $role
     * @return Users
     */
    public function setRole(\Roles $role = null)
    {
        $this->role = $role;
        return $this;
    }

    /**
     * Get role
     *
     * @return Roles 
     */
    public function getRole()
    {
        return $this->role;
    }

after you update the database schema with the above annotated definition, you should be able to see the foreign key on ‘users’ table. But you will notice, there is no unique key generated. to establish the relationship properly while creating new user, you can follow the code example below:

$role = $em->getRepository("Roles")->findOneBy(array("name"=>"admin"));

$user = new Users();
$user->setUserName("testusername");
$user->setEmail("testemail@domain.com");
$user->setRole($role);

$em->persist($user);
$em->flush();

Many To Many Relationship:

New story for new relationship. Suppose, our users do have some skills. A single user can have multiple skills and in the similar way, a single skill can be acquired by multiple users. So, here we are talking about a Many to Many relationship between users and skills.

From relational database design basics, we know, in such scenario, in database we will have to establish a new table which connects to users table and expertise table. And a user/skill pair will be unique on that table. Luckily, as we are modifying entities instead of database, its became very much easy for us for doctrines strong abstraction support.

Lets see the doctrine relationship establishment in users entity to contains multiple skills.

use Doctrine\ORM\Mapping as ORM;

/**
 * Users
 *
 * @Table(name="users")
 * @Entity
 */
class Users
{
     //Other declarations

     /**
     * @var \Doctrine\Common\Collections\ArrayCollection
     * @ManyToMany(targetEntity="Expertises", inversedBy="users")
     * @JoinTable(name="users_expertises")
     **/
    private $expertises;

    public function __construct() {
        $this->expertises = new \Doctrine\Common\Collections\ArrayCollection();
    }

    /**
     * Get expertises
     *
     * @return PdExpertises
     */
    public function getExpertises()
    {
        return $this->expertises;
    }
}

//expertise entity

use Doctrine\ORM\Mapping as ORM;

/**
 * Expertises
 *
 * @Table(name="expertises")
 * @Entity
 */
class Expertises
{
     //other declarations.....
     /**
     * @ManyToMany(targetEntity="Users", mappedBy="expertises")
     **/
    private $users;

    public function __construct() {
        $this->users = new \Doctrine\Common\Collections\ArrayCollection();
    }

    /**
     * Get users
     *
     * @return Users
     */
    public function getUsers()
    {
        return $this->users;
    }
}

From the above code, you will see, we haven’t declared any setter method for the properties. Because, we won’t need it. we will be able to perform our task by operating on ArrayCollection very fine. Lets see a basic example usages:

        $expertise = $this->em->getRepository("Expertises")->find(1);
                
        $user = new Users();
        //other properties set        
        $user->getExpertises()->add($expertise);
        
        $this->em->persist($user);
        $this->em->flush();

Final Words:

So, do some exercises, see how surprisingly doctrine relationship establishment making our life easier to do several operations. If you are having any issue to understand, ask me by commenting. Happy coding 🙂

Related

Filed Under: Database Tagged With: doctrine, php

About Rana Ahsan

Rana is a passionate software engineer/Technology Enthusiast.
Github: ranacseruet

Comments

  1. Peter Furesz says

    September 28, 2015 at 5:36 pm

    Nice tutorial! Thank you, great job!

    Reply
  2. Rakib Ahmed Shovon says

    November 14, 2015 at 1:25 am

    can u tell something about entity owner side and inverse side ?

    Reply
  3. vahid says

    November 18, 2015 at 5:39 am

    Hi Thank you for your tutorial.
    i have type table that have Many-to-Many relationship with category and many to many relation table (categoryOftype table) have One-to-Many relationship with items table how i do this with entity relationship in doctrine 2 .
    tanks

    Reply

Leave a Reply Cancel reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Email Subscription

Never miss any programming tutorial again.

Popular Tutorials

  • How To Work With JSON In Node.js / JavaScript
  • PHP HTML5 Video Streaming Tutorial
  • How To Work With C# Serial Port Communication
  • LinQ Query With Like Operator
  • Facebook C# API Tutorials
  • LinQ To SQL Database Update Operations In C#
  • Using Supervisord Web Interface And Plugin
  • Tutorial On Uploading File With CodeIgniter Framework / PHP
  • Utilizing Config File In C#.NET Application
  • Using GIT Plugin For Netbeans IDE

Recent Tutorials

  • Building Auth With JWT – Part 1
  • Document Your REST API Like A Pro
  • Understanding Golang Error Handling
  • Web Application Case Studies You Must Read
  • Getting Started With Golang Unit Testing
  • Getting Started With Big Data Analytics Pipeline
  • NodeJS Tips And Tricks For Beginners
  • Apple Push Notification Backend In NodeJS
  • Web Based Universal Language Translator, Voice/Text Messaging App
  • How To Dockerize A Multi-Container App From Scratch

Recent Comments

  • S. Chalisque on PHP HTML5 Video Streaming Tutorial
  • Armorik on Generate HTTP Requests using c#
  • iswaps on PHP HTML5 Video Streaming Tutorial
  • TAKONDWA on PHP HTML5 Video Streaming Tutorial
  • rorenzo on PHP HTML5 Video Streaming Tutorial

Archives

Resources

  • CodeSamplez.com Demo

Tags

.net apache api audio aws c# cache cloud server codeigniter deployment doctrine facebook git github golang htaccess html5 http image java javascript linq mysql nodejs oop performance php phpmyadmin plugin process python regular expression scalability server smarty ssh tfs thread tips ubuntu unit-test utility web application wordpress wpf

Copyright © 2010 - 2022 · CodeSamplez.com ·

Copyright © 2022 · Streamline Pro Theme on Genesis Framework · WordPress · Log in