Home > Blockchain >  Select objects without some properties in Symfony 3.4
Select objects without some properties in Symfony 3.4

Time:10-27

I have one problem in Symfony that I cannot solve. I have one Entity class e.g. Category where I have e.g. $id, $name, $description, OneToMany User[] $members, OneToMany Book[] $books Now... I need to get all categories (e.g. WHERE description IS NOT NULL) but in results, I don't want to have $books.
I need Category with id, name, description and [member1, member2...] but NO books. I use something like:

$em->getRepository('AppBundle:Category')->findAll();

CodePudding user response:

You can use ->select('fieldA, fieldB') to query specific fields.

Create a method in your repository to make your custom query:

public function findAllWithoutBooks()
{
    return $this->createQueryBuilder('c')
        ->select('c.id, c.name, c.description')
        ->leftJoin('c.members', 'm')
        ->addSelect('m.id AS member_id, m.name AS member_name')
        ->andWhere('c.description IS NOT NULL')
        ->getQuery()
        ->getResult()
}

And use it like any other method:

$em->getRepository('AppBundle:Category')->findAllWithoutBooks();

CodePudding user response:

Doctrine by default uses Lazy fetching, meaning the books are not queried until after you call $category->getBooks(). Using partial references is not needed as detailed below, unless the mapping fetch declaration was changed to EAGER for the association, provided you are not calling $category->getBooks();

Alternatively, a custom query using the partial keyword can be used to explicitly select only the specified fields and hydrate partial Category and associated User objects.

Use of partial objects is tricky. Fields that are not retrieved from the database will not be updated by the UnitOfWork even if they get changed in your objects. You can only promote a partial object to a fully-loaded object by calling EntityManager#refresh() or a DQL query with the refresh flag.

Example Query

$qb = $em->getRepository('AppBundle:Category')->createQueryBuilder('c');
$categories = $qb->select('partial c.{id, name, description}')
   ->leftJoin('c.members', 'm')
   ->addSelect('partial m.{id, name}')
   ->where($qb->expr()->isNotNull('c.description'))
   ->getQuery()
   ->getResult();

Result

array(
    Category {
        id,
        name,
        description,
        members => array(
            User {
                id,
                name
            },
            User {
                id,
                name
            }
            ...
        ),
    },
    Category {
        id,
        name,
        description,
        members => array(
            User {
                id,
                name
            },
            User {
                id,
                name
            }
            ...
        )
    }
    ...
)
  • Related