Consider using Doctrine ORM for Entities

Created on 19 October 2012, almost 13 years ago
Updated 26 June 2023, about 2 years ago

This issue is about considering to use or not Doctrine ORM(Object-Relational Mappers) for entity mapping to database schema.

Problem/Motivation

We have built over the past home made Drupal ORM for Entity management. Right now, we are thinking about replacing hook_entity_info() arrays with annotations, requiring entities to be plugins. We should use the plugin system sparingly as it will set the tone for community.

Drupal as of version 6, implements an ORM. Hooks can add data to nodes from anywhere they want, whether it maps to a database table or not. However, the ORM is "naked": there is no abstraction on data access. Everything is loaded at once into a single big blob data that gets returned from node_load().

Drupal as of version 7 improved a lot this. The Entity API matches the entity structure to the relational database and adds an abstracted layer for CRUD operations, but, the loading of an entity is still not optimized.

Drupal in its 8-dev version changed the entity_info() arrays into annotations, so this is a good step and a good direction. Entities are currently re-factored against the plugin system, using a EntityManager to govern persistence. It is exactly how Doctrine ORM actually work.

Because an ORM is more robust, it can do a lot more optimization under the hood. Complex relationships can be modeled in a database-independent way, even tying to non-SQL systems like the file system, Services, etc.

  • The Entity system is really complex, you have to first extend a base class or implement the EntityInterface.
  • Entities themselves contains reference to controllers, via annotations, this should not appear in a data object.
  • Annotations are not used on a per-field basis, but as a meta-data stack which helps the entity manager to understand how to deal with the Entity.

Refactored solution

  • Does not need to extend a base class or to implement an interface.
  • Generates Physical Data Model from classes themselves.
  • No need for Schema API anymore in the long run.
  • Uses annotations the correct way.
  • Have a meta-data caching system included.

Entities are generated and looks like the following:

<?php

namespace Drupal\entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * Node
 *
 * @ORM\Table(name="node")
 * @ORM\Entity
 */
class Node
{
  /**
   * @var integer
   *
   * @ORM\Column(name="nid", type="integer", nullable=false)
   * @ORM\Id
   * @ORM\GeneratedValue(strategy="IDENTITY")
   */
  protected $nid;

  /**
   * @var \Drupal\entity\User
   *
   * @ORM\ManyToOne(targetEntity="Drupal\entity\User")
   * @ORM\JoinColumns({
   *   @ORM\JoinColumn(name="uid", referencedColumnName="uid")
   * })
   */
  protected $user;
}
?>
<?php

namespace Drupal\entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * User
 *
 * @ORM\Table(name="users")
 * @ORM\Entity
 */
class User
{
  /**
   * @var integer
   *
   * @ORM\Column(name="uid", type="integer", nullable=false)
   * @ORM\Id
   * @ORM\GeneratedValue(strategy="IDENTITY")
   */
  protected $uid;

  /**
   * @var string
   *
   * @ORM\Column(name="name", type="string", length=60, nullable=false)
   */
  protected $name;

  /**
   * @var string
   *
   * @ORM\Column(name="pass", type="string", length=128, nullable=false)
   */
  protected $pass;

}
?>

Remaining tasks

Decide if we want to go in this direction or not.

Resources

📌 Task
Status

Closed: won't fix

Version

11.0 🔥

Component
Entity 

Last updated 26 minutes ago

Created by

🇫🇷France Sylvain Lecoy

Live updates comments and jobs are added and updated live.
  • Needs issue summary update

    Issue summaries save everyone time if they are kept up-to-date. See Update issue summary task instructions.

Sign in to follow issues

Comments & Activities

Not all content is available!

It's likely this issue predates Contrib.social: some issue and comment data are missing.

Production build 0.71.5 2024