'How get @ORM\index

Good afternoon, please tell me how to get the column data:

{@ORM\Index(name="localities_names_idx", columns={"name_ru", "name_cn", "name_en"})

I tried using queryBuilder :

$qb
    ->select('a')
    ->from(Locality::class, 'a')
    ->where('a.name_ru = :name_ru')
    ->andWhere('a.area is null')
    ->setParameter('name', 'Moscow');

$query = $qb->getQuery();

Without success

I need it for:

$em = $this->entityManager;
$qb = $em->createQueryBuilder();
$qb
    ->select('a')
    ->from(Locality::class, 'a')
    ->where('a.name_ru = :name_ru')
    ->andWhere('a.area is null')
    ->setParameter('name', 'Москва');

$query = $qb->getQuery();
$result = $query->getResult(Query::HYDRATE_SCALAR);
$location = new Location();
$location->setLocality($result[0]['a_id']);
$location->setAddress($address);
$em->persist($location);
$em->flush();

return $location->getId();


Solution 1:[1]

Edit: This turned into a review, but might as well keep it here


You're using index wrong.

I'm guessing you're using it incorrectly. I'm assuming you want an index for faster search. However, the way you do now you've created a combined index. Example:

{@ORM\Index(name="thing_colour_idx", columns={"thing", "colour"})
Thing | Colour
--------------
Car    Blue
Car    Red
Bike   Green
Bike   Yellow

If you always (or at least most of the time) select by both columns, eg you always search for a BLUE+CAR, or a GREEN+BIKE, than this is the way to go.
However, if you to select all Thing=Car, without colour, then this index does nothing. You want this:

indexes={
    @ORM\Index(name="thing_idx", columns={"thing"}),
    @ORM\Index(name="colour_idx", columns={"colour"})
}

You're not using getResult as intended

You do ->getResult(Query::HYDRATE_SCALAR), but then follow it up with a ->setLocality($result[0]['a_id']). Unless you have performace issues, you dont work with IDs, thats a problem for Doctrine, not you. You should only care about objects:

$locality = $em
    ->createQueryBuilder()
    ->from(Locality::class, 'a')
    ->where('a.name_ru = :name_ru')
    ->andWhere('a.area is null')
    ->setParameter('name', '??????') // <- btw, this should be 'name_ru', same as two lines heigher
    ->getQuery()
    ->getSingleResult();

$location = new Location();
$location->setLocality($locality);

Dont use the querybuilder like that, use a repository

You're now placing service logic and query logic in one code. That is incorrect. An example of the way Symfony is intented:

class LocalityRepository extends ServiceEntityRepository{
    public function __construct(ManagerRegistry $registry)
    {
        parent::__construct($registry, Locality::class);
    }

    public function getLocalityByRuName(string $name): Locality 
    {
        return $this->createQueryBuilder('a')
            ->where('a.name_ru = :name_ru')
            ->andWhere('a.area is null')
            ->setParameter('name_ru', $name);
            ->getQuery();
            ->getSingleResult();
    }
}

class YourService
{
    public function __construct(
        private LocalityRepository $localityRepository
    ){}

    public function somethingSomething()
    {
        $locality = $this->localityRepository->getLocalityByRuName('??????');
        $location = new Location();
        $location->setLocality($locality);
    }
}

Final note: Try not to use a ->flush() in a service. The job of a service is to do work, not to decide what to do it. A controller decides when something is done. Suppose you have another service which in which you alter things, but DONT want to flush them. You can now no longer use any service method that flushes.

Solution 2:[2]

The error was that there were no name properties Ru

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 Aleksey Blossom