Symfony3多对多关联级联持久化问题:已配置cascade={"persist"}仍报错
我之前也踩过Doctrine这个坑!明明已经给ShopProducts#shopProductImages关联加了cascade={"persist"},结果还是弹出未配置级联的错误,给你几个靠谱的排查和解决方向:
检查双向关联的配置完整性
多对多关联分「拥有方」和「被拥有方」,Doctrine只会优先识别拥有方的级联配置。先确认你的映射是不是搞反了:
比如ShopProducts作为拥有方的映射应该是这样(注意inversedBy指向关联实体的属性):/** * @ORM\ManyToMany(targetEntity="ShopProductImages", inversedBy="shopProducts", cascade={"persist"}) * @ORM\JoinTable(name="shop_products_images") */ private $shopProductImages;而
ShopProductImages作为被拥有方的映射要对应mappedBy:/** * @ORM\ManyToMany(targetEntity="ShopProducts", mappedBy="shopProductImages") */ private $shopProducts;如果你的业务场景需要从
ShopProductImages侧关联ShopProducts,那也要给这个被拥有方的关联加上cascade={"persist"}。确保操作的是拥有方的关联集合
哪怕配置对了级联,如果你是从被拥有方发起的关联操作,Doctrine也不会触发级联。比如你不能只做$shopProductImage->addShopProduct($shopProduct),必须同时(或者优先)操作拥有方的集合:$shopProduct->addShopProductImage($shopProductImage),这样Doctrine才会识别到级联规则。临时显式持久化关联实体(排查用)
如果暂时找不到配置问题,可以先手动持久化关联的ShopProductImages实例,再持久化主实体:$entityManager->persist($shopProductImage); $entityManager->persist($shopProduct); $entityManager->flush();要是这样能解决,说明你的级联配置肯定哪里没配对;如果还是报错,大概率是缓存问题。
清理Doctrine元数据缓存
Doctrine经常会缓存旧的映射配置,哪怕你改了代码也不生效。运行这几个命令清缓存试试:php bin/console doctrine:cache:clear-metadata php bin/console doctrine:cache:clear-query php bin/console doctrine:cache:clear-result
另外还可以检查下有没有拼写错误,比如cascade={"persist"}是不是写成了单值字符串(虽然Doctrine兼容,但数组格式更稳妥),或者关联属性名和映射里的名称是否完全一致。
内容的提问来源于stack exchange,提问作者Sruj

