0

私はこのエンティティを持っています:

<?php

namespace ProductBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Gedmo\Mapping\Annotation as Gedmo;
use ProductBundle\DBAL\Types\StatusType;
use ProductBundle\DBAL\Types\FieldType;
use Fresh\Bundle\DoctrineEnumBundle\Validator\Constraints as DoctrineAssert;

/**
 * @ORM\Entity
 * @ORM\Table(name="product_detail")
 */
class ProductDetail {

    /**
     * @ORM\Id
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $id;

    /**
     * @ORM\ManyToOne(targetEntity="ProductDetail")
     * @ORM\JoinColumn(name="parent", referencedColumnName="id")
     */
    protected $parent;

    /**
     * @ORM\Column(type="string", length=255)
     */
    protected $description;

    /**
     * @ORM\Column(type="string", length=255)
     */
    protected $label;

    /**
     * @var string $field_type
     * @DoctrineAssert\Enum(entity="ProductBundle\DBAL\Types\FieldType")
     * @ORM\Column(name="field_type", type="FieldType", nullable=false)
     */
    protected $field_type;

    /**
     * @ORM\Column(name="values_text", type="string")
     */
    protected $values_text;

    /**
     * @ORM\Column(type="string", length=255)
     */
    protected $measure_unit;

    /**
     * @var string $status
     * @DoctrineAssert\Enum(entity="ProductBundle\DBAL\Types\StatusType")
     * @ORM\Column(name="status", type="StatusType", nullable=false)
     */
    protected $status;

    /**
     * @Gedmo\Timestampable(on="create")
     * @ORM\Column(name="created", type="datetime")
     */
    protected $created;

    /**
     * @Gedmo\Timestampable(on="update")
     * @ORM\Column(name="modified", type="datetime")
     */
    protected $modified;

    /**
     * @ORM\ManyToMany(targetEntity="CategoryBundle\Entity\Category", inversedBy="pd_detail")
     * @ORM\JoinTable(name="product_detail_has_category",
     *      joinColumns={@ORM\JoinColumn(name="category", referencedColumnName="id")},
     *      inverseJoinColumns={@ORM\JoinColumn(name="detail", referencedColumnName="id")}
     *      )
     */
    protected $category;

    /**
     * @ORM\ManyToMany(targetEntity="ProductBundle\Entity\DetailGroup", inversedBy="productDetail")
     * @ORM\JoinTable(name="detail_group_has_product_detail",
     *      joinColumns={@ORM\JoinColumn(name="group", referencedColumnName="id")},
     *      inverseJoinColumns={@ORM\JoinColumn(name="detail", referencedColumnName="id")}
     *      )
     */
    protected $detail_group;

    public function __construct() {
        $this->detail_group = new \Doctrine\Common\Collections\ArrayCollection();
        $this->category = new \Doctrine\Common\Collections\ArrayCollection();
    }

    public function getId() {
        return $this->id;
    }

    public function setParent(ProductDetail $parent = null) {
        $this->parent = $parent;
    }

    public function getParent() {
        return $this->parent;
    }

    public function setDescription($description) {
        $this->description = $description;
    }

    public function getDescription() {
        return $this->description;
    }

    public function setLabel($label) {
        $this->label = $label;
    }

    public function getLabel() {
        return $this->label;
    }

    public function setFieldType($field_type) {
        $this->field_type = $field_type;
    }

    public function getFieldType() {
        return $this->field_type;
    }

    public function setValuesText($values_text) {
        $this->values_text = $values_text;
    }

    public function getValuesText() {
        return $this->values_text;
    }

    public function setMeasureUnit($measure_unit) {
        $this->measure_unit = $measure_unit;
    }

    public function getMeasureUnit() {
        return $this->measure_unit;
    }

    public function setStatus($status) {
        $this->status = $status;
    }

    public function getStatus() {
        return $this->status;
    }

    public function setCreated($param) {
        $this->created = $param;
        return true;
    }

    public function getCreated() {
        return $this->created;
    }

    public function setModified($param) {
        $this->modified = $param;
        return true;
    }

    public function getModified() {
        return $this->modified;
    }

    public function setCategory(Category $category) {
        $this->category[] = $category;
    }

    public function getCategory() {
        return $this->category;
    }

    public function setDetailGroup(DetailGroup $detailGroup) {
        $this->detail_group[] = $detailGroup;
    }

    public function getDetailGroup() {
        return $this->detail_group;
    }

}

namespace ProductBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Gedmo\Mapping\Annotation as Gedmo;
use Fresh\Bundle\DoctrineEnumBundle\Validator\Constraints as DoctrineAssert;

/**
 * @ORM\Entity
 * @ORM\Table(name="detail_group")
 */
class DetailGroup {

    /**
     * @ORM\Id
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $id;

    /**
     * @ORM\ManyToOne(targetEntity="DetailGroup")
     * @ORM\JoinColumn(name="parent", referencedColumnName="id")
     */
    protected $parent;

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

    /**
     * @ORM\Column(type="string", length=255)
     */
    protected $description;

    /**
     * @Gedmo\Timestampable(on="create")
     * @ORM\Column(name="created", type="datetime")
     */
    protected $created;

    /**
     * @Gedmo\Timestampable(on="update")
     * @ORM\Column(name="modified", type="datetime")
     */
    protected $modified;

    /**
     * @ORM\ManyToMany(targetEntity="ProductBundle\Entity\ProductDetail", mappedBy="detail_group", cascade={"all"})
     */
    protected $productDetail;

    public function __construct() {
        $this->productDetail = new \Doctrine\Common\Collections\ArrayCollection();
    }

    public function getId() {
        return $this->id;
    }

    public function setParent(DetailGroup $parent = null) {
        $this->parent = $parent;
    }

    public function getParent() {
        return $this->parent;
    }

    public function setName($name) {
        $this->name = $name;
    }

    public function getName() {
        return $this->name;
    }

    public function setDescription($description) {
        $this->description = $description;
    }

    public function getDescription() {
        return $this->description;
    }

    public function setCreated($param) {
        $this->created = $param;
        return true;
    }

    public function getCreated() {
        return $this->created;
    }

    public function setModified($param) {
        $this->modified = $param;
        return true;
    }

    public function getModified() {
        return $this->modified;
    }

    public function setProductDetail(ProductDetail $productDetail) {
        $this->productDetail[] = $productDetail;
    }

    public function getProductDetail() {
        return $this->productDetail;
    }

}

これは私のProductDetailType.phpフォームです:

<?php

namespace ProductBundle\Form;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;

class ProductDetailType extends AbstractType {

    public function buildForm(FormBuilderInterface $builder, array $options) {
        $builder
                ->add('category', 'entity', array('class' => 'CategoryBundle:Category', 'property' => 'name', 'required' => false, 'multiple' => true, 'expanded' => false))
                ->add('detail_group', 'entity', array('class' => 'ProductBundle:DetailGroup', 'property' => 'name', 'required' => false, 'multiple' => true, 'expanded' => false))
                ->add('parent', 'entity', array('class' => 'ProductBundle:ProductDetail', 'property' => 'label', 'required' => false))
                ->add('description', 'text', array('required' => false))
                ->add('label')
                ->add('field_type', 'choice', ['choices' => \ProductBundle\DBAL\Types\FieldType::getChoices()])
                ->add('values_text', 'collection', array('type' => 'text', 'allow_add' => true, 'allow_delete' => true, 'by_reference' => false))
                ->add('measure_unit', 'text', array('required' => false))
                ->add('status', 'choice', ['choices' => \ProductBundle\DBAL\Types\StatusType::getChoices()]);
    }

    public function setDefaultOptions(OptionsResolverInterface $resolver) {
        $resolver->setDefaults(array(
            'data_class' => 'ProductBundle\Entity\ProductDetail'
        ));
    }

    public function getName() {
        return 'prod_detail_create';
    }

}

そして、これは私のものcreateAction()です:

/**
 * Handle product details creation
 *
 * @Route("/product_detail/create", name="product_detail_create")
 * @Method("POST")
 * @Template("ProductBundle:ProductDetail:new.html.twig")
 */
public function createAction(Request $request) {
    $entity = new ProductDetail();
    $form = $this->createForm(new ProductDetailType(), $entity);
    $form->handleRequest($request);

    if ($form->isValid()) {
        $em = $this->getDoctrine()->getManager();
        $entity->setValuesText(serialize($form->get('values_text')->getData()));
        $em->persist($entity);
        $em->flush();

        return $this->redirect($this->generateUrl('product_detail_list'));
    }

    return $this->render('ProductBundle:ProductDetail:new.html.twig', array(
                'entity' => $entity,
                'form' => $form->createView(),
    ));
}

新しいレコードを挿入しようとすると、次のエラーが発生します。

パラメータ [7, 2] を指定して「INSERT INTO product_detail_has_category (category, detail) VALUES (?, ?)」を実行中に例外が発生しました:

SQLSTATE [23000]: 整合性制約違反: 1452 子行を追加または更新できません: 外部キー制約が失敗しました ( product_detail_has_category, CONSTRAINT fk_product_detail_has_category_product_detail1FOREIGN KEY ( detail) REFERENCES product_detail( id) ON UPDATE CASCADE)

ログを確認すると、次のように表示されます。

DEBUG - "START TRANSACTION"
DEBUG - INSERT INTO product_detail (description, label, field_type, values_text, measure_unit, status, created, modified, parent) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
DEBUG - INSERT INTO product_detail_has_category (category, detail) VALUES (?, ?)
DEBUG - "ROLLBACK" 

product_detail が挿入されず、関係を作成しようとする理由がわかりません。何が問題なのですか?

4

2 に答える 2

0

次のいずれかを実行できます。

  • で設定された$categoryフィールドに設定cascade={"PERSIST"}@ManyToManyます。

    これにはコントローラー自体の変更は必要ありませんが、カスケードの定義が好きかどうかによって異なります。

  • 永続化する前にCategoryオブジェクトを手動で永続化します。ProductDetail

    $em = ...; // your entity manager
    
    // first, manually persist any category that is found
    foreach ( $productDetail->getCategory() as $c ){ 
        $em->persist($c);
    }
    
    // then, persist top-level object
    $em->persist($productDetail);
    
    // finally, flush everything
    $em->flush();
    

これが少し役立つことを願っています...

于 2013-08-15T08:14:34.390 に答える