Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Extending Doctrine Entity in order to add business logic

I'm trying to practice a good design and extending Doctrine entity. My extended class, the model basically, will have extra business logic + access to the entity basic data.

I am using Doctrine 2.2.1 & Zend Framework 1.11.4 & php 5.3.8

When I use DQL, doctrine return successfully the Model entity. When I use Doctrine native find() function, it returns nothing :(.

HELP...

This is how it rolls:

Bootstrap.php:

    $classLoader = new \Doctrine\Common\ClassLoader('Entities', APPLICATION_PATH.'/doctrine');
    $classLoader->register();
    $classLoader = new \Doctrine\Common\ClassLoader('Models', APPLICATION_PATH);
    $classLoader->register();

Model in APPLICATION_PATH\models\User.php:

namespace Models;
use Doctrine\ORM\Query;

/**
 * Models\User
 *
 * @Table(name="user")
 * @Entity
 */
class User extends \Entities\User {

public function __wakeup() {
    $this->tools = new Application_App_Tools();
}

Entity retrieval functions:

DOESN'T WORK:

$userEntity = $registry->entityManager->find('Models\User', $userEntity);

WORKS:

$qry = $qb
        ->select('u')
        ->from('Models\User','u'); 
like image 387
ohadwkn Avatar asked Aug 29 '12 14:08

ohadwkn


People also ask

What is Doctrine entity?

Doctrine has a command-line interface that allows you to access the SchemaTool, a component that can generate a relational database schema based entirely on the defined entity classes and their metadata. For this tool to work, you need to create an executable console script as described in the tools chapter.

How does Doctrine work?

Doctrine uses the Identity Map pattern to track objects. Whenever you fetch an object from the database, Doctrine will keep a reference to this object inside its UnitOfWork. The array holding all the entity references is two-levels deep and has the keys root entity name and id.

What design pattern does Doctrine mainly uses for its ORM?

You probably have heard that before. And how it works in Doctrine is it uses a so-called proxy pattern.

What is Doctrine database?

The Doctrine Project is the home to several PHP libraries primarily focused on database storage and object mapping. The core projects are the Object Relational Mapper (ORM) and the Database Abstraction Layer (DBAL) it is built upon.


2 Answers

You shouldn't add the business logic to the entities, you should use models for that instead. One way of doing it would be:

  1. Use models for business logic.
  2. Create custom Doctrine 2 repositories for your all your database queries (DQL or otherwise) [1].
  3. Leave your entities alone.

In practise this means that models are plain PHP classes (or maybe framework extended depending on what your're using) but your models have no relation to your database. Your models do however, instantiate your custom Doctrine 2 repositories. E.g. a UserRepository might contain a method called getUserById. Within your repositories is where your run your actual queries and return entity instances for the models to work with.

[1] http://docs.doctrine-project.org/en/latest/reference/working-with-objects.html#custom-repositories

like image 124
Luke Avatar answered Oct 03 '22 16:10

Luke


As I understand Doctrine, entityManager is responsible only for persistent entities, and extending Entities\User entity with Model\User will create another entity (stored in same table as stated in docblock), but not managed by entityManager or in collision with it because you probably didn't mention @InheritanceType("SINGLE_TABLE") in Entities\User docblocks:

Read this docs for more info http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/inheritance-mapping.html

like image 27
Ivan Hušnjak Avatar answered Oct 03 '22 17:10

Ivan Hušnjak