Doctrine: UniqueEntity with Many-to-Many field

2019-07-07 17:25发布

I have a class Repair that should have unique entries for "name", "device", and "color". I.e. there should only be one "Replace screen" for "iPhone 5c" in colours "red" and "green".

However, Symfony throws an exception:

An exception occurred while executing 'SELECT t0.id AS id_1, t0.name AS name_2, t0.minutes AS minutes_3, t0.safetytime AS safetytime_4, t0.cost AS cost_5, t0.device_id AS device_id_6 FROM repair t0 WHERE t0.name = ? AND t0.device_id = ? AND repairs_colors.color_id = ?' with params ["Replace screen", 2, {}]:

Catchable Fatal Error: Object of class Doctrine\ORM\PersistentCollection could not be converted to string

Here is my Entity definition (Repair.php):

/**
 * @ORM\Table(name="repair")
 * @ORM\Entity(repositoryClass="AppBundle\Repository\RepairRepository")
 * @UniqueEntity(fields={"name", "device", "colors"}, message="There already exists a repair job with name {{ value }} for this device and these colours.")
 */
class Repair {

    /**
     * @var string
     * @ORM\Column(name="name", type="string", length=255)
     */
    private $name;

    /**
     * @ORM\ManyToOne(targetEntity="Device", inversedBy="repairs")
     * @ORM\JoinColumn(name="device_id", referencedColumnName="id")
     */
    private $device;

    /**
     * @ORM\ManyToMany(targetEntity="Color", inversedBy="repairs")
     * @ORM\JoinTable(name="repairs_colors",
     *      joinColumns={@ORM\JoinColumn(name="repair_id", referencedColumnName="id")},
     *      inverseJoinColumns={@ORM\JoinColumn(name="color_id", referencedColumnName="id")}
     *      ) 
     */
    private $colors;
}

I understand that Symfony is passing an empty array of colours instead of the actual colours set. But why?

1条回答
萌系小妹纸
2楼-- · 2019-07-07 17:42

Here is the source code of the UniqueEntity constraint in Symfony.

As default Symfony will internaly do a query like :

->findBy(array(
'name'=>$entity->getName(),
'device'=>$entity->getName(),
'colors'=>$entity->getColors() // <- Precisely here, doctrine is not able to traduce that in a SQL query.
));

Workaround : Create you own Repository method, and use it in your constraint :

/**
 * @ORM\Table(name="repair")
 * @ORM\Entity(repositoryClass="AppBundle\Repository\RepairRepository")
 * @UniqueEntity(fields={"name", "device", "colors"}, repositoryMethod="getSimilarRepairs")
 */
class Repair {
    // ...
}
查看更多
登录 后发表回答