Symfony数据库查询返回异常数据、重复数据问题排查求助
问题原因分析
你遇到的两个异常表现本质是同一个根源:Doctrine的**身份映射(Identity Map)**机制触发了异常逻辑,核心原因是CongesEchangeRtt实体类的主键配置错误。
Doctrine查询返回实体对象时,会根据实体标注的主键字段值做内存缓存:如果多条数据库记录的主键值被判定为相同,Doctrine会直接返回内存中已经实例化的第一个对象,不会读取新行的字段数据,刚好匹配你遇到的两种现象:
- 自定义DQL查询时,同一个用户的多条记录因为主键值重复,仅保留第一条返回的结果
- findBy查询时,统计的匹配行数和数据库一致,但所有行实例化时都复用了第一个同主键的对象,出现内容全部重复的问题
排查步骤
- 打开
CongesEchangeRtt实体类文件,检查主键注解配置,确认是否错误地将非唯一字段(比如用户登录名字段eLogin)设置为了唯一主键,或是联合主键配置不符合表的实际唯一规则。
错误配置示例参考:
/** * @ORM\Id * @ORM\Column(name="e_login", type="string", length=255) */ private $eLogin;
修复方案
根据你的表结构选择对应方案即可:
- 如果表有独立的自增主键字段(比如
id):直接将@Id注解移到自增主键字段上,删除其他字段的@Id注解即可。 - 如果表使用联合主键(比如
eLogin+eDateJour两个字段联合唯一作为主键):按规则配置联合主键即可,参考代码:
/** * @ORM\Id * @ORM\Column(name="e_login", type="string", length=255) */ private $eLogin; /** * @ORM\Id * @ORM\Column(name="e_date_jour", type="date") */ private $eDateJour;
- 临时验证可以绕过实体映射,直接返回数组结果,将查询方法中的
getResult()替换为getArrayResult(),不会触发Doctrine的实体缓存逻辑,参考代码:
return $this->createQueryBuilder('c') ->andWhere('c.eLogin IN (:val)') ->andWhere('c.eDateJour LIKE :date') ->setParameter('val', $agents) ->setParameter('date', $date . "%") ->getQuery() ->getArrayResult() ;
内容的提问来源于stack exchange,提问作者alex
相关产品推荐
相关产品推荐

