Symfony/Doctrine: PostgreSQL Migration Issue – Undefined column error only in HTTP Kernel (CLI works)
I'm working on a Symfony 7.3 project running on PHP 8.2. I recently migrated the database from MySQL to PostgreSQL, and since then, I've encountered a highly specific issue with Doctrine's ORM that only manifests in the HTTP context.
The Problem
When I try to fetch data from the user table via an HTTP request, I receive the following SQL error:
SQLSTATE[42703]: Undefined column: 7
ERROR: column t0.id does not exist
LINE 1: SELECT t0.id AS id_1, t0.email AS email_2, t0.password AS pa...
This error is exclusive to any code executed within the HTTP Kernel (e.g., Controllers, Listeners).
Factual Observations (Crucial)
1. Command Line Interface (CLI) Works Fine ✔️
When executing queries directly via the Symfony console (which uses the exact same Doctrine configuration and database connection), everything works perfectly. This confirms the table public.user and the column id exist.
2. Isolated Debug Controller Fails ❌
A minimal debug controller fetching the User entity triggers the error.
3. Working Counter-Example (The Clue) 💡
A structurally identical controller for the Customer entity (table name customer, which is not a reserved PostgreSQL keyword) works without error. This strongly points to a conflict with the reserved keyword user.
Entity and Database Details
User Entity (Abridged)
The entity uses standard Doctrine annotations:
// src/Entity/User.php
#[ORM\Entity(repositoryClass: 'App\Repository\UserRepository')]
#[ORM\Table(name: 'user')] // Problematic line
class User {
// ... ORM\Id and ORM\Column definitions
}
Database Structure
- DBMS: PostgreSQL
- Table Name in DB:
user(lowercase, public schema) - PostgreSQL Fact: The word
useris a reserved SQL keyword.
The Temporary Fix & The Core Question ⚠️
I discovered that the error is resolved by manually forcing Doctrine to quote the table name using backticks in the Entity mapping:
// Temporary Fix
#[ORM\Table(name: '`user`')]
While this solution works, I reject it as a permanent fix. It introduces an unsightly exception into my clean entity code, only addresses this single reserved word, and does not provide a future-proof, global guarantee that Doctrine will correctly handle other reserved PostgreSQL keywords (e.g., group, order, etc.) without manual intervention.
The Question
Based on the confirmed root cause (PostgreSQL reserved keyword user not being reliably quoted in the HTTP context) and the desire for a clean, global solution:
What is the underlying Doctrine DBAL or Symfony configuration setting (e.g., in doctrine.yaml) that must be applied to the PostgreSQL connection to globally enforce the correct quoting behavior for all reserved SQL keywords, thereby allowing the Entity mapping to remain clean (#[ORM\Table(name: 'user')]) and guaranteeing future compatibility with PostgreSQL?