orm icon indicating copy to clipboard operation
orm copied to clipboard

[ObjectRepository] Error with query select when property is camelCase without `name` attribute

Open cavasinf opened this issue 2 years ago • 6 comments
trafficstars

Bug Report

Q A
BC Break yes
Version 2.15.3

Summary

Switching from one database to multiple databases for one Symfony application, and following the doc How to Work with Multiple Entity Managers and Connections.

When using extend of EntityRepository on custom Repository, every camelCase SELECT generated are wrongs.

Current behavior

When the entity property name is camelCase:

use Doctrine\ORM\Mapping as ORM;

#[ORM\Column]
protected ?string $fullName = null;

The repository tries to select the exact same column name in SQL version t0.fullName or in the database the true column name is full_name.

An exception occurred while executing a query: SQLSTATE[42S22]: Column not found: 1054 Unknown column 't0.fullName' in 'field list'

Looking through the code, the problem comes from the ClassMetadaInfo -> AttributeDriver -> AttributeReader -> convertToAttributeInstances().

fieldName = "fullName"
type = null
scale = null
length = null
unique = false
nullable = false
precision = null

This code only looks at attribute names/values. When describing the property, if I add the name of the property as in the database (in kebab_case) it works as untended.

use Doctrine\ORM\Mapping as ORM;

- #[ORM\Column]
+ #[ORM\Column(name: 'full_name')]
protected ?string $fullName = null;

Mapping result:

fieldName = "fullName"
type = null
scale = null
length = null
unique = false
nullable = false
precision = null
columnName = "full_name"

How to reproduce

  1. Create an entity with a camelCase property
use Doctrine\ORM\Mapping as ORM;

#[ORM\Entity(repositoryClass: UserRepository::class)]
class User
{
    #[ORM\Column]
    protected ?string $fullName = null;
}
  1. Create a Repository that extends EntiRepository
use Doctrine\ORM\EntityRepository;

#[ORM\Entity(repositoryClass: UserRepository::class)]
class UserRepository extends EntityRepository
{
  // ...
}
  1. Do a ~~findBy~~ QueryBuilder from that repository.
public function filterQb(array $filter = []): QueryBuilder
{
    $qb = $this->createQueryBuilder('user');

    if (isset($filter['fullName'])) {
        $qb
            ->andWhere('user.fullName LIKE :fullName')
            ->setParameter('fullName', "%{$filter['fullName']}%")
        ;
    }

    return $qb;
}
  1. See Symfony error

Expected behavior

As when using the ServiceEntityRepository camelCase properties should be converted to kebab_case when defining the SELECT elements for the query.

cavasinf avatar Jul 06 '23 14:07 cavasinf

I can't reproduce this issue. Can you share a reproducer as a repository?

derrabus avatar Jul 08 '23 13:07 derrabus

Sorry, I was on vacation. I'll try to do a Symfony project this week that represents this case.

cavasinf avatar Jul 17 '23 12:07 cavasinf

Here you go: https://github.com/cavasinf/doctrine-orm-10821

From your tests:

  • It is not a findBy (sorry) but a QueryBuilder
  • Maybe you forgot to add multiple connections for doctrine? image

cavasinf avatar Jul 25 '23 08:07 cavasinf

Maybe you’re using different naming strategies for the different connections?

mpdude avatar Feb 03 '24 23:02 mpdude

Can't you see the reproducer? Have you tried it?

cavasinf avatar Feb 03 '24 23:02 cavasinf

No I haven’t tried it. I just saw your issue, noticed that it sounds like a naming strategy configuration issue.

Also you’re using two entity managers on the same set of entities. Not sure that is a supported configuration.

mpdude avatar Feb 04 '24 00:02 mpdude