Laravel with Eloquent or Doctrine ?

Jose Miguel Quisbert
4 min readMay 26, 2020

--

When I started my career, the first framework I learned was Symfony and then I met Laravel. Ultimately Laravel is composed of several Symfony and Zend components, but they are used differently.

You may wonder how to compare an ODM with an ORM, but the purpose is to compare how the framework relates to data persistence. The goal is not to make a categorical judgment on whether one ORM is better than another, but to raise some points that you should take into account when doing this analysis with your team or involved.

Laravel uses Eloquent and Symfony Doctrine, as these are components it is possible to use them separately from the framework.

Let's split this article in this topics:

  • Resume of main diferences and architecture
  • Learning curve
  • Performance
  • Laravel support
  • Relationships:
  • Schema builder (or migrations )
  • Testability
  • Mongo support (Bonus)
  • Conclusion

What is the principal diferences between Doctrine and Eloquent?

  • Data Source Architectural Patterns

Data Source Architectural Patterns: Active Record (160), Data Mapper (165).

Eloquent makes use of the Active Record, described by Martin Fowler, where the Model will be the representation of the database and also through it the operations in the database will be made, as in the example below:

$user = new App\User;
$user->name = 'Francesco';
$user->email = 'francesco@foo.bar';
$user->save();

Doctrine makes use of it depends on an EM — Entity Manager — to be able to perform the actions in the database and the entities are representations of the database tables.

<?phpnamespace Bundle\Entities;use Doctrine\ORM\Mapping as ORM;/**
* @ORM\Entity
* @ORM\Table(name="user")
*/
class User
{
/**
* @ORM\Id
* @ORM\GeneratedValue
* @ORM\Column(type="integer")
*/
private $id;
/**
* @ORM\Column(type="string")
*/
private $name;

/**
* @ORM\Column(type="boolean")
*/
private $active = false;

Learning curve

Doctrine

  • Bureaucratic
  • More lines of code
  • Annotations

Eloquent

  • Faster
  • No Annotations

Indeed Doctrine requires a bureaucratic requirements using Entity Manager and building the queries to select, insert, update, delete the data, this steps take time.

On the other hand, Eloquent provides Active Record, so can simply Model::save(), Model::update() and other functions, this is a very helpful feature, but sometimes can bring some unwished queries especially when we talk about relationships.

Otherwise, Doctrine always require the EM to apply changes to database, so the entities are just PHP Objects. So when you use Doctrine the repositories are really repositories because is more faithful to the pattern as a way of working with the database.

$user = new User;  
$user->setName(‘Jhon’);

EntityManager::persist($user);
EntityManager::flush();

If you are used to using Eloquent and are starting with Doctrine you will notice that due to bureaucracy the development will be less agile, but this will improve according to the team’s learning.

Performance

Doctrine

  • Entity Manager

Eloquent

  • Query Builder

Eloquent Model require more memory to load the relationships, but lazy load is really helpful during the work.

Especially when we talk about relationships, this ORM has a bad performance writing SQL Queries and it can cost some issues for the database or application.

Laravel support

Since a wrote this article, doctrine has compatibility with Laravel 7.0.

Form request

Relationships

Doctrine

<?php/** @Entity */class User 
{
/**
* @ManyToOne(targetEntity="Address")
* @JoinColumn(name="address_id", referencedColumnName="id")
*/

private $address = false;
}

Eloquent

<?phpclass User extends Model
{
public function address(){
return $this->hasMany(Address::class, 'address_id')
}}

Schema builder (or migrations )

Both have this functionality, just change the syntax.

Doctrine

Eloquent

public function up()
{
Schema::create('roles', function (Blueprint $table) {
$table->increments('id');
$table->softDeletes();
$table->timestamps();
});
}
public function down()
{
Schema::drop('permission_role');
}

Testability

Eloquent

If you use Laravel as described in the documentation and his author and not trying use "repositories" with Eloquent, create tests trying to abstract the persistence and use of the database, Eloquent does not provide you with a good experience in unit testing because you will need mock relations and theirs resources and the `factory()` helper give to us more speed to create an arrange.

$user = new User();
$set->setRelation('role', $role)
$set->setRelation('cars', collect($cars))

You can find here more examples to test Laravel with models and how Eloquent is supported by framework, this book is wrote by Jeffrey Way himself will give to you more cases.

Doctrine

With Doctrine and repository pattern test can be more easily because allow us mock the database when testing Controllers and Services.

Disclaimer:

You can use `factory()` helper too if you are using this package:

http://www.laraveldoctrine.org/docs/current/orm/testing

Mongo Support

Both are supported to work with MongoDB, maintaining the functionalities, respectively:

Eloquent

Doctrine

Conclusion

As you could realized, be pragmatic in your decision when it comes to looking at what to use. Doctrine is good and very organized, but you need to analyze if there is really a need to add this complexity to your system. Sometimes when developing an application that would better use Data Mapper pattern.

However Eloquent gives agility and speed in addition to using the onboard ORM and with full support by the framework.

As you may have seen, it will be up to your team to evaluate each item on the scale. In my opinion, using components that have already been curated by the community and authors of Laravel is more recommended.

Based in my experience using both with Laravel in projects using MongoDB and MySQL as database, I prefer uso all onboard Laravel components.

Looking forward to seeing your comments, blog posts or Medium.com articles!

Looking forward to seeing your comments, blog posts or Medium.com articles!

--

--