別のエンティティとの OneToMany 関係を持つエンティティがあります。親エンティティを永続化するときに、子に重複が含まれないようにしたいと考えています。
これが私が使用しているクラスです。割引コレクションには、特定のクライアントに対して同じ名前の 2 つの製品を含めることはできません。
割引のコレクションを持つ Client エンティティがあります。
/**
* @ORM\Entity
*/
class Client {
/**
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* @ORM\Column(type="string", length=128, nullable="true")
*/
protected $name;
/**
* @ORM\OneToMany(targetEntity="Discount", mappedBy="client", cascade={"persist"}, orphanRemoval="true")
*/
protected $discounts;
}
/**
* @ORM\Entity
* @UniqueEntity(fields={"product", "client"}, message="You can't create two discounts for the same product")
*/
class Discount {
/**
* @ORM\Id
* @ORM\Column(type="string", length=128, nullable="true")
*/
protected $product;
/**
* @ORM\Id
* @ORM\ManyToOne(targetEntity="Client", inversedBy="discounts")
* @ORM\JoinColumn(name="client_id", referencedColumnName="id")
*/
protected $client;
/**
* @ORM\Column(type="decimal", scale=2)
*/
protected $percent;
}
ご覧のとおり、割引クラスにUniqueEntityを使用してみましたが、問題は、バリデーターがデータベースにロードされているもの (空) のみをチェックしているように見えるため、エンティティが永続化されると、「SQLSTATE[23000]: Integrity」が表示されることです。制約違反」。
コレクションの制約を確認しましたが、エンティティではなく、フィールドのコレクションのみを処理しているようです。
コレクション全体ではなく、各エンティティに適用する制約を定義できるAllバリデータもあります。
カスタムバリデーターを作成するか、毎回コールバックバリデーターを作成する以外に、データベースに永続化する前にエンティティコレクションの制約が全体として存在するかどうかを知る必要があります。