Symfony 6 + Doctrine 操作多PostgreSQL数据库时使用Repository出现SQLSTATE[42P01]表不存在错误
我太懂你这种头疼的感觉了——直接用DBAL能查到WebServices库的表,EntityManager也能正确获取实体元数据,可一用Repository就报表不存在,简直离谱!咱们一步步拆解问题,把这个坑填上:
1. 先确认实体管理器的映射是否生效
先跑个命令验证WebServices实体管理器有没有正确加载你的实体:
php bin/console doctrine:mapping:info --em=web_services
如果输出里能看到App\Entity\WebServices\Country和App\Entity\WebServices\Translate,并且对应的表名是gis.country(或你设置的schema+表名),那映射的基础配置是对的;如果看不到,那得先检查doctrine.yaml里的web_services实体管理器映射路径、前缀有没有写错,比如dir是不是指向了src/Entity/WebServices,prefix是不是App\Entity\WebServices。
2. 给Repository绑定正确的实体管理器
你现在的Repository继承自ServiceEntityRepository,但构造函数里只传了注册表和实体类,没指定要用哪个实体管理器!在多库场景下,这会导致Repository默认用default管理器去查,自然找不到WebServices库的表。修改Repository的构造函数:
// src/Repository/WebServices/CountryRepository.php public function __construct(ManagerRegistry $registry) { // 第三个参数指定实体管理器名称 parent::__construct($registry, Country::class, 'web_services'); }
TranslateRepository也得做同样的修改,确保它也用web_services管理器。
3. 精准配置实体的Schema和表名
PostgreSQL的Schema是区分大小写的,如果你数据库里的Schema是小写的gis,那实体注解里的Schema也得严格对应:
// 正确写法(对应数据库的gis schema) #[ORM\Table(schema: "gis", name: "country")]
别像你之前那样写成sig(应该是笔误吧?),大小写和名称必须和数据库里的完全一致。
4. 给WebServices连接设置Schema搜索路径
有时候Doctrine生成查询时,不会自动带上Schema前缀,你可以直接在DBAL连接配置里指定搜索路径,让PostgreSQL自动优先查gisSchema:
# config/packages/doctrine.yaml doctrine: dbal: connections: # ... 其他配置 web_services: url: '%env(resolve:DATABASE_WS_URL)%' server_version: '13.5' options: - { name: search_path, value: 'gis,public' }
5. 清缓存!清缓存!清缓存!
Symfony和Doctrine的缓存经常会搞事情,尤其是修改了映射配置后,一定要清干净:
php bin/console cache:clear php bin/console doctrine:cache:clear-metadata php bin/console doctrine:cache:clear-query php bin/console doctrine:cache:clear-result
最后验证
先注释掉你自定义的findAll方法,用父类默认的findAll试试,如果能查到数据,那就是你自定义QueryBuilder的问题;如果还是报错,再回头检查上面的步骤,重点看实体管理器的绑定和Schema配置。
备注:内容来源于stack exchange,提问作者bcag2

