doctrine / orm

Doctrine Object Relational Mapper (ORM)
https://www.doctrine-project.org/projects/orm.html
MIT License
9.86k stars 2.5k forks source link

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

Open cavasinf opened 11 months ago

cavasinf commented 11 months ago

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;

}

2. Create a Repository that extends `EntiRepository`
```php
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;
    }
  2. 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.

derrabus commented 11 months ago

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

cavasinf commented 11 months ago

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

cavasinf commented 10 months ago

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

From your tests:

mpdude commented 4 months ago

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

cavasinf commented 4 months ago

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

mpdude commented 4 months ago

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.