Symfony 7.2.1中Doctrine Criteria的In/NotIn查询异常问题
问题分析与解决方案
可能的原因
Doctrine的Criteria在处理关联实体的in/notIn条件时,直接传入实体对象数组可能存在解析异常,尤其是UUID作为主键的场景——框架可能没有正确将实体对象转换为对应主键值进行查询,导致条件失效。
解决方案
1. 改用实体ID数组替代实体对象数组
提取实体的UUID主键数组传入条件,避免Doctrine解析实体对象时的潜在问题:
// 提取Ean和Shelf的ID数组 $eanIds = array_map(fn(Ean $ean) => $ean->getId(), $eanObjects); $shelfIds = array_map(fn(Shelf $shelf) => $shelf->getId(), $shelves); $criteria = Criteria::create() ->andWhere(Criteria::expr()->in('ean', $eanIds)) ->andWhere(Criteria::expr()->notIn('shelf', $shelfIds)); $match = $this->entityManager->getRepository(EanShelfQuantity::class)->matching($criteria);
2. 验证实体关联映射正确性
检查EanShelfQuantity中关联字段的映射是否正确配置,确保关联指向UUID主键:
// EanShelfQuantity.php use Doctrine\ORM\Mapping as ORM; /** * @ORM\Entity(repositoryClass=EanShelfQuantityRepository::class) */ class EanShelfQuantity { // ...其他字段 /** * @ORM\ManyToOne(targetEntity=Ean::class) * @ORM\JoinColumn(name="ean_id", referencedColumnName="id", nullable=false) */ private $ean; /** * @ORM\ManyToOne(targetEntity=Shelf::class) * @ORM\JoinColumn(name="shelf_id", referencedColumnName="id", nullable=false) */ private $shelf; // ...getter/setter }
3. 用QueryBuilder显式构建查询
如果Criteria仍有问题,直接使用QueryBuilder明确关联逻辑,避免隐式解析问题:
$eanIds = array_map(fn(Ean $ean) => $ean->getId(), $eanObjects); $qb = $this->entityManager->createQueryBuilder() ->select('esq') ->from(EanShelfQuantity::class, 'esq') ->where('esq.ean IN (:eanIds)') ->andWhere('esq.shelf NOT IN (:shelves)') ->setParameter('eanIds', $eanIds) ->setParameter('shelves', $shelves); $match = $qb->getQuery()->getResult();
补充说明
纯SQL查询正常是因为直接操作了主键字段,而Doctrine的Criteria/QueryBuilder在处理实体对象数组时,需要依赖映射配置和内部解析逻辑,UUID类型的主键可能因类型转换或版本兼容问题导致解析失败,改用ID数组或显式关联查询可规避这类问题。
内容的提问来源于stack exchange,提问作者sauvox
相关产品推荐
相关产品推荐

