2

I work with Symfony2 and Doctrine and I have a question regarding entities.

In a performance worries, I'm wondering if it is possible to use an entity without going all the associations?

Currently, I have not found another way to create a model inheriting the class with associations and associations specify NULL in the class that inherits.

thank you in advance


OK, a little detail, it's for a API REST (JSON).

This is my class :

/**
 * Offerequipment
 *
 * @ORM\Table(name="offer_equipment")
 * @ORM\Entity(repositoryClass="Charlotte\OfferBundle\Repository\Offerequipment")
*/

class Offerequipment
{
/**
 * @var integer
 *
 * @ORM\Column(name="id", type="integer")
 * @ORM\Id
 * @ORM\GeneratedValue(strategy="AUTO")
 */
private $id;

/**
 * @ORM\ManyToOne(targetEntity="Charlotte\OfferBundle\Entity\Offer")
 * @ORM\JoinColumn(name="offer_id", referencedColumnName="id")
 */
private $offer;

/**
 * @ORM\ManyToOne(targetEntity="Charlotte\ProductBundle\Entity\Equipment")
 * @ORM\JoinColumn(name="equipment_id", referencedColumnName="id")
 */
private $equipment;

/**
 * @VirtualProperty
 *
 * @return String
 */
public function getExample()
{
   return $something;
}

and with QueryBuilder method, i can't get my virtual properties or getters.

Thanks for your help :)

elixenide
  • 44,308
  • 16
  • 74
  • 100
Vincent
  • 31
  • 3
  • Do you mean, you want to prevent selecting associated entities when selecting a particular entity with QueryBuilder? – BentCoder Feb 15 '16 at 15:54
  • If yes, then to prevent lazy loading/selecting associated entities directly in your query then you can add `...->getQuery()...->setHint(Query::HINT_FORCE_PARTIAL_LOAD, true)...->getResult();` method to your query builder. [Some doctrine best practises and lazy load](http://www.inanzzz.com/index.php/post/5muq/some-doctrine-best-practises-and-lazy-load) and [HINT_FORCE_PARTIAL_LOAD](http://www.doctrine-project.org/api/orm/2.3/class-Doctrine.ORM.Query.html#HINT_FORCE_PARTIAL_LOAD) – BentCoder Feb 15 '16 at 16:15
  • Yes, I want to get only one associated entity, not all. (eg : i want equipment's entity and not offer's entity and keep virtual property of my equipment) – Vincent Feb 16 '16 at 10:38
  • Then you can just use `HINT_FORCE_PARTIAL_LOAD` in your query builder. – BentCoder Feb 16 '16 at 10:39

3 Answers3

2

Look at Serialization.

By serialising your entities, you can choose to exclude or expose a property of an entity when you render it.

Look at the Symfony built-in Serializer and/or JMSSerializer.

Otherwise, you can use QueryBuilder and DQL to choose what fields you want to fetch in your queries.

Like this, you can make your own find method in the Repository of your entities.

// src/AcmeBundle/Repository/FooRepository

class FooRepository extends \Doctrine\ORM\EntityRepository

    // ...

    public function find($id) {
        $queryBuilder = $this->createQueryBuilder('e')
            ->select('e.fieldA', 'e.fieldB') // selected fields
            ->where('e.id = :id') // where statement on 'id'
            ->setParameter('id', $id);

        $query = $queryBuilder->getQuery();

        $result = $query->getResult();
    }

    // ...
}

Don't forget define the Repository in the corresponding Entity.

/**
 * Foo.
 *
 * @ORM\Entity(repositoryClass="AcmeBundle\Repository\FooRepository")
 */
class Foo
{
    // ...
}
chalasr
  • 12,971
  • 4
  • 40
  • 82
2

By default Doctrine will not automatically fetch all of the associations in your entities unless you specifically each association as EAGER or unless you are using a OneToOne association. So if you are looking to eliminate JOINs, you can just use Doctrine in its default state and it won't JOIN anything automatically.

However, you this will not alleviate all of your performance concerns. Say, for example, you are displaying a list of 50 products in your application on a single page and you want to show their possible discounts, where discounts are an association on your product entity. Doctrine will create 50 additional queries just to retrieve the discount data unless you explicitly join the discount entity in your query.

Essentially, the Symfony profiler will be your friend and show you when you should be joining entities on your query - don't just think that because you aren't joining associations automatically that your performance will always be better.

Jason Roman
  • 8,146
  • 10
  • 35
  • 40
1

Finally, after many days, I've found the solution to select only one entity.

VirtualProperties are found :)

public function findAllByOffer($parameters) 
{
   $queryBuilder = $this->createQueryBuilder('oe');
   $queryBuilder->select('oe, equipment');
   $queryBuilder->join('oe.equipment', 'equipment');

   $result = $queryBuilder->getQuery()->setHint(Query::HINT_FORCE_PARTIAL_LOAD, true)->getResult();

   return $result;
}
Vincent
  • 31
  • 3