Skip to content
Advertisement

How to get data from a column with this annotation @ORMindex

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

{@ORMIndex(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();

Advertisement

Answer

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:

{@ORMIndex(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={
    @ORMIndex(name="thing_idx", columns={"thing"}),
    @ORMIndex(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.

User contributions licensed under: CC BY-SA
9 People found this is helpful
Advertisement