在1-N关联中用新的替换数组集合项时防止完整性约束违规

时间:2016-10-28 09:44:32

标签: symfony doctrine-orm

在我的Symfony应用程序中,如果我先摆脱$em->flush();,我会收到integrity constraint violation on "car.code"错误,因为AAA仍然在DB中。如果这是一个有10个人的批处理过程,我需要flush 20次,这不是一个好主意。所以问题是,有没有办法在最后将flush简化为 1 ?我的意思是现有的记录会以某种flush粘贴新记录之前被删除。

CURRENT LOGIC

// Find the "person" object
$person = .....;

// Remove all existing "car" objects
$person->getCars()->clear();
$em->flush();

// Create new "car" objects
foreach ($request as $data) {
    $car = new Car;
    $car->setCode($data->code);
    // ......
}
$em->flush();

请求

PUT persons/10/cars.json
{
  [
    {
      "code": "AAA",
      "status": "ByeA"
    },
    {
      "code": "EEE",
      "status": "ByeE"
    }
  ]
}

数据库中的当前数据

SELECT * FROM person;
id
--
10

SELECT * FROM car;
id  code  status  person_id
--  ----  ------  ---------
1   AAA   HelloA  10
2   BBB   HelloB  10
3   CCC   HelloC  10
4   DDD   HelloD  10

处理请求后

SELECT * FROM person;
id
--
10

SELECT * FROM car;
id  code  status  person_id
--  ----  ------  ---------
5   AAA   ByeA    10
6   EEE   ByeE    10

1到N ENTITY STRUCTURE

/**
 * @ORM\Table()
 * @ORM\Entity()
 */
class Person
{
    private $id;

    /**
     * @ORM\OneToMany(
     *     targetEntity="Car", mappedBy="person",
     *     cascade={"persist", "remove"}, orphanRemoval=true
     *     )
     */
    private $cars;

    public function __construct()
    {
        $this->cars = new ArrayCollection();
    }

    //....
}

/**
 * @ORM\Table(uniqueConstraints={@ORM\UniqueConstraint(columns={"code"})})
 * @ORM\Entity()
 */
class Car
{
    private $id;

    private $code;

    private $status;

    /**
     * @ORM\ManyToOne(targetEntity="Person", inversedBy="cars")
     * @ORM\JoinColumn(name="person_id", referencedColumnName="id", nullable=false)
     */
    private $person;

    //....
}

1 个答案:

答案 0 :(得分:0)

这个逻辑怎么样?

// Find the "person" object
$person = .....;
$cars   = [];

// Create new "car" objects
foreach ($request as $data) {
    $car = new Car;
    $car->setCode($data->code);
    // ......

    $cars[] = $car;
}

$person->setCars($cars);    

$em->persist();
$em->flush();

Car实体

public function setPerson(Person $person)
{
     $this->person = $person;

     return $this;
}

Person实体

public function setCars($cars)
{
    $this->cars = new ArrayCollection();

    return $this->addCars($cars);
}

public function addCars($cars)
{
    foreach ($cars as $car)
    {
        $this->addCar($car);
    }

    return $this;
}

public function addCar(Car $car)
{
    if (!$this->cars->contains($car)
    {
        $this->cars->add($car);
        $car->setPerson($this);
    }

    return $this;
}