【问题标题】:Doctrine 2 persist only save header object why?Doctrine 2 坚持只保存标头对象,为什么?
【发布时间】:2016-09-23 09:51:18
【问题描述】:

我想保存带有采购订单详细信息的采购订单标题。这是我的 PurchaseOrder 实体类=>

 namespace AppBundle\Entity;

 use AppBundle\Entity\PurchaseInvoiceDetail;
 use Doctrine\Common\Collections\ArrayCollection;
 use Doctrine\ORM\Mapping as ORM;


/**
* PurchaseOrder
*
* @ORM\Table(name="purchase_order", indexes={@ORM\Index(name="fk_purchase_order_supplier1_idx", columns={"supplier_id"})})
* @ORM\Entity
*/
class PurchaseOrder
{
/**
 * @var PurchaseOrderDetails
 *
 * @ORM\OneToMany(targetEntity="AppBundle\Entity\PurchaseOrderDetails", mappedBy="purchaseOrder",cascade={"cascade"})
 * @JMS\Type("ArrayCollection<FinanceBundle\Entity\AutoAllocation>")
 */
private $purchaseOrderDetails;


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

public function addPurchaseOrderDetail(PurchaseOrderDetails $purchaseOrderDetails)
{
    $this->purchaseOrderDetails->add($purchaseOrderDetails);
}

/**
 * @return PurchaseOrderDetails
 */
public function getPurchaseOrderDetails()
{
    return $this->purchaseOrderDetails;
}

/**
 * @param PurchaseOrderDetails $purchaseOrderDetails
 */
public function setPurchaseOrderDetails($purchaseOrderDetails)
{
    $this->purchaseOrderDetails = $purchaseOrderDetails;
}

}

和 PurchaseOrderDetail 类一样 =>

<?php

namespace AppBundle\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
* PurchaseOrderDetails
*
* @ORM\Table(name="purchase_order_details", indexes={@ORM\Index(name="fk_purchase_order_details_purchase_order1_idx", columns={"purchase_order_id"}),    @ORM\Index(name="fk_purchase_order_details_invt_item1_idx", columns={"id_item"})})
  * @ORM\Entity
  */
class PurchaseOrderDetails
{


/**
 * @var \AppBundle\Entity\PurchaseOrder
 *
 * @ORM\ManyToOne(targetEntity="AppBundle\Entity\PurchaseOrder",inversedBy="purchaseOrderDetails")
 * @ORM\JoinColumns({
 *   @ORM\JoinColumn(name="purchase_order_id", referencedColumnName="id")
 * })
 */
private $purchaseOrder;
/**
 * Set purchaseOrder
 *
 * @param \AppBundle\Entity\PurchaseOrder $purchaseOrder
 *
 * @return PurchaseOrderDetails
 */
public function setPurchaseOrder(\AppBundle\Entity\PurchaseOrder $purchaseOrder = null)
{
    $this->purchaseOrder = $purchaseOrder;

    return $this;
}

/**
 * Get purchaseOrder
 *
 * @return \AppBundle\Entity\PurchaseOrder
 */
public function getPurchaseOrder()
{
    return $this->purchaseOrder;
}
}

我在 symfony 3.1 中的 php 代码如下=>

$em = $this->getDoctrine()->getManager();
$purchaseOrder = new PurchaseOrder();
$puchaseOrderDetail = new PurchaseOrderDetails();
$puchaseOrderDetail->setPrice(100);
$purchaseOrder->setPurchaseOrderDetails($puchaseOrderDetail);
$puchaseOrderDetail->setPurchaseOrder($purchaseOrder);
$em->persist($purchaseOrder);
$em->flush();

没有发生错误,只有采购订单保持不变,采购订单详细信息不存在

【问题讨论】:

    标签: php doctrine entity persistence symfony-3.1


    【解决方案1】:

    您没有保留详细信息对象。要么用

    手动持久化它
    $em->persist($purchaseOrderDetail);
    

    或修复

    cascade={"persist"}
    

    PurchaseOrder::$purchaseOrderDetails@ORM\OneToMany 注释中(cascade={"cascade"} 可能是一个错字)。

    【讨论】:

    • 我可以看到我已经完成了这个问题的第一个代码框架,但没有工作
    • @Sameera 你做了什么伙计?如果您的意思是级联持续存在,那您就错了(cascade=cascade vs cascade=persist)
    【解决方案2】:

    你也需要persistPurchaseOrderDetails

    下面的代码应该保存你的两个实体。

    $em = $this->getDoctrine()->getManager();
    $purchaseOrder = new PurchaseOrder();
    $puchaseOrderDetail = new PurchaseOrderDetails();
    $puchaseOrderDetail->setPrice(100);
    $purchaseOrder->setPurchaseOrderDetails($puchaseOrderDetail);
    $puchaseOrderDetail->setPurchaseOrder($purchaseOrder);
    $em->persist($purchaseOrder);
    $em->persist($puchaseOrderDetail);
    $em->flush();
    

    正如@Finwe 所提到的,如果您的业务逻辑需要,并且您不想在创建新的PurchaseOrder 时单独PurchaseOrderDetails 实体persist。你可以考虑配置cascade_persist。这将自动保留关联的实体。

    为此,将级联选项添加到您的关联配置中:

    @ORM\OneToMany(targetEntity="AppBundle\Entity\PurchaseOrderDetails", mappedBy="purchaseOrder",cascade={"persist"})
    

    【讨论】:

    • 我可以看到我已经完成了这个问题的第一个代码框架,但没有工作
    • 你已经完成了cascade={"cascade"}。我想,你应该有cascade={"persist"} 来级联子级中的新数据,就像它发生在父级中一样。您可以让cascade={"all"} 处理所有内容(插入、更新和删除)。请看看它是否有效!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-19
    • 1970-01-01
    • 2011-12-07
    • 1970-01-01
    相关资源
    最近更新 更多