1

just curious .. I have some code like so:

//$em is EntityManager of Doctrine
//$className is a type that uses polymorphism (subtype of a parent type)
$pricing = $em->getRepository($className)->findOneBy(array(
    'active' => true,
    'product_id' => (int) $this->id
));

//gets serialization of certain variables of $className
return $pricing->getSerialization();

But ... instead of calling findOneBy outside of $className, can I move getSerialization() method inside the Entity (which is $className), and return class-parameters from there?

I imagine it is not possible, since Entity cannot read itself. Correct?

The problem I am trying to solve is. ... In the example above Entity is populated via Doctrine and then it returns data. Therefore I have to use another class to populate the entity. Without Doctrine I know it's possible to do things such as read data from inside the Entity i.e. via mysqli, and then return properties directly or via a method. In other words, do I absolutely need another location (class/function/method outside of Entity) to populate the entity?

Sample Entity looks like so

class Pricing
{
    function getSerialization(){}

    /**
     * @var integer @Column(name="id", type="integer", nullable=false)
     *      @Id
     *      @GeneratedValue(strategy="IDENTITY")
     */
    protected $id;
    //etc, a typical Doctrine Entity
}
Dennis
  • 7,907
  • 11
  • 65
  • 115
  • No. Doctrine entities are just plain objects and cannot load themselves from the database. What you could do is create a method ProductRepository::getSerializedPricing($productId). But sticking to the code you have is probably the best. – Cerad Nov 19 '15 at 02:09

1 Answers1

2

Yes, the instance of an entity class can read itself.
But I guess your question should have been: "Can a Doctrine entity load and read itself?". The answer to that is no...

Loading of entities is managed by doctrine internals. If you would want the entity classes to load themselves it would mean injecting an EntityManager into the entity class.

This is a bad idea, I quote @BryanM. his answer on another stackoverflow question that covers this nicely:

It is not a good idea to allow an entity object to rely on the entity manager. It ties the entity to the persistence layer, which was a problem Doctrine 2 was specifically trying to solve. The biggest hassle in relying on the entity manager is that it makes your model hard to test in isolation, away from the database.

You should probably be relying on service objects to handle the operations that rely on the entity manager.

It means you need to take care of loading entities externally. I still don't see the problem with getSerialization. It can be inside the Entity class and can be used after the entity is loaded right?

If you want to do loading and serializing at once I would suggest making a PricingService in which you inject the repository or entity manager and where you define a public methods that does all that. For example:

<?php

use Application\Entity\Pricing;
use Doctrine\ORM\EntityManager;
use Doctrine\ORM\EntityRepository;

class PricingService
{
    /**
     * @var EntityManager
     */
    protected $entityManager;

    /**
     * @param EntityManager $entityManager
     */
    public function __construct(EntityManager $entityManager)
    {
        $this->entityManager = $entityManager;
    }
    
    /**
     * @return EntityRepository;
     */
    protected function getRepository()
    {
        return $this->entityManager->getRepository(`Application\Entity\Pricing`);
    }

    /**
     * @param $params
     * @return array 
     */
    public function findSerializedBy($params)
    {
        $pricing = $this->getRepository()->findOneBy($params);
        return $pricing->getSerialization();
    }
}

Now you can work with your PricingService directly:

$serializedPricing = $pricingService->findSerializedBy(array(
    'active' => true,
    'product_id' => (int) $this->id
));

You can of course generalize your service by adding another parameter with the $classname.

Community
  • 1
  • 1
Wilt
  • 41,477
  • 12
  • 152
  • 203
  • @Dennis Did creating a Service like this solve your issue? Or was this not the answer that you were looking for? :D – Wilt Nov 23 '15 at 08:01