Как получить Doctrine сортируемую "Ошибка повторяющейся записи" - PullRequest
0 голосов
/ 11 июля 2020

У меня проблема с сортируемым расширением doctrine.

Во-первых, у меня есть сущность House с отношением 1: n к сущности HouseImage (настройка для сохранения позиции изображения) и сущность HouseImage 1 : 1 выпуск в объект File.

class House
{
    /**
     * @var HouseImage[]|Collection
     *
     * @ORM\OneToMany(
     *     targetEntity="HouseImage",
     *     mappedBy="houses",
     *     cascade={"persist", "remove"},
     *     orphanRemoval=true
     * )
     * @ORM\OrderBy({"position" = "ASC"})
     */
    protected $images;

}


/**
 * HouseImage
 *
 * @ORM\Table(name=house_image)
 * @ORM\Entity(repositoryClass="Gedmo\Sortable\Entity\Repository\SortableRepository")
 */
class HouseImage {


    /**
     * @var House
     *
     * @ORM\ManyToOne(
     *     targetEntity="House",
     *     inversedBy="images",
     * )
     * @ORM\JoinColumn(
     *     name="house_id",
     *     referencedColumnName="id",
     *     onDelete="SET NULL"
     * )
     * @Gedmo\SortableGroup
     */
    protected $houses;

    /**
     * @var File
     *
     * @ORM\OneToOne(
     *     targetEntity="File",
     * )
     *
     * @ORM\JoinColumn(
     *     name="image_id",
     *     referencedColumnName="id",
     *     nullable=false,
     * )
     */
    protected $image;

    /**
     * @var integer
     *
     * @Gedmo\SortablePosition
     * @ORM\Column(name="position", type="integer")
     */
    protected $position;
    
    
    ....
}

//so i create some HouseImage-Objects

$HouseImage = new HouseImage();
$HouseImage->setImage($myFile);

$HouseImage2 = new HouseImage();
$HouseImage2->setImage($myFile2);

$HouseImage3 = new HouseImage();
$HouseImage3->setImage($myFile3);

//add first image-relation to house
$house->setImages([$HouseImage]);
$em->persist($house);
$em->flush();

//add second image-relation, should be inserted at first position 
$house->setImages([$HouseImage2, $HouseImage]);

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

//add new list of image-relation 
$house->setImages([$HouseImage2, $HouseImage3]);

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

/// после гриппа sh entitymanager произошла эта ошибка

An exception occurred while executing 'INSERT INTO house_image (position, house_id, image_id) VALUES (?, ?, ?)' with params [0, 123, 999]:\n
SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry '999' for key 'UNIQ_E0C3790C3DA5256D

произошла некоторая ошибка с фабрикой форм

$data['images'] = [

    [
        'house' => 181,
        'image' => 123
    ],
    [
        'house' => 181,
        'image' => 1234
    ],
    [
        'house' => 181,
        'image' => 12345
    ],
];

$form   = $formFactory->create(HouseType::class, $houseObject);#
$form->submit($data, false);

Вопрос: Как мне обновить позицию HouseImage в списке, добавив список HouseImage, или Как я могу очистить все объекты перед вставкой полного нового списка HouseImage-Releations

Изменить: Я исправил свою проблему, удалив метод addImage () и реализовав этот метод setImage ():

public function setImages(Collection $images): void
{
    $col = new ArrayCollection();
    $i = 0;
    /* @var $image HouseImage */
    foreach ($images as $image) {
        $image->setHouse($this);
        $image->setPosition($i++);

        $col->add($image);
    }
    $this->images = $col;
}

1 Ответ

0 голосов
/ 11 июля 2020

Ваш способ создания сущностей изображения дома немного неверен, вы можете определить, что сущность дома должна каскадно сохранять вашу коллекцию HouseImage. Вы должны добавить это в свой объект House:

class House
{
  function __construct()
  {
    $this->images = new ArrayCollection();
  }

  public function addHouseImage(HouseImage $houseImage)
  {
     $this->images->add($houseImage);
     $houseImage->setHouse($this);
  }
}

Также переименуйте $ homes в $ house в своем HouseImage. Вы связываете HouseImage с House (немного домов) . Также не забудьте связать HouseImage с сущностью File. Если вы хотите установить позицию после последнего изображения на новом изображении, вы делаете это в функции addHouseImage или где-нибудь еще в вашем приложении. С приведенным выше кодом ваш код может выглядеть следующим образом:

$image1 = ...;
$image2 = ...;
$image3 = ...;

$house->addHouseImage($image1);
add2.
add2.

// This will persist all house images along with house.
$em->persist($house);
$em->flush();

Если я не затронул что-то, связанное с вашим вопросом, пожалуйста, дайте мне знать
Также исключение

'INSERT INTO house_image (position, house_id, image_id) VALUES (?,?,?)' С params [0, 123, 999]: \ n SQLSTATE [23000]: нарушение ограничения целостности: 1062 Повторяющаяся запись '999' для ключа ' UNIQ_E0C3790C3DA5256D

сообщает вам, что уже существует файл с идентификатором 999, и вы пытаетесь установить 2 объекта HouseImage в один объект File. Я не могу обнаружить это в вашем коде, но я почти уверен, что это происходит где-то в вашем коде.

...