1

我在让我的学说实体提取到我的 ZF2 表格时遇到问题。我对 ZF2 和 Doctrine(以及类表继承)都很陌生。我已经阅读了几乎所有的 ZF2 和 Doctrine 文档,但似乎仍然无法弄清楚如何让它工作。

为了简要解释系统,有一个名为 Policy 的主要实体。Policy 实体包括一个 Proposer 实体和一个 PolicyProduct 实体,以及其他几个列。

我在 PolicyProduct 实体中使用类表继承,因为我有 3 种不同的产品类型,每种都需要不同的数据。3 个产品实体是 TouringCaravan、StaticCaravan 和 Parkhome。

Policy 实体只能有 1 个 Proposer 和 1 个 PolicyProduct。

所有实体的每一列都有 getter 和 setter 方法。

我显示的表单包括来自 Policy 实体和 PolicyProduct 实体的字段。

为了显示表单,我首先获取 Policy 实体和 Policy Fieldset。然后将 Policy Fieldset 设置为基础。

$policyEntity = $entityManager->getRepository('Policy\Entity\Policy')->find($policyId);
$policyFieldset = $formElementManager->get('policy_form_policy_fieldset');
$policyFieldset->setUseAsBaseFieldset(true);

然后我获取 PolicyProduct 特定字段集并将其添加到 policyFieldset。

eg
$productFieldset = $formElementManager->get('tourers_form_touring_fieldset');
$policyFieldset->add($productFieldset);

然后我将 policyFieldset 添加到表单中,将其与 Policy 实体绑定,并返回完成的表单。

$productForm->add($policyFieldset);
$productForm->bind($policyEntity);
return $productForm;

需要注意的是,我将DoctrineModule\Stdlib\Hydrator\DoctrineObject as DoctrineHydrator用作每个字段集的 hydrator。init()然后我在每个字段集的方法中调用以下内容 。

// Example from PolicyFieldset
$hydrator = new DoctrineHydrator($this->objectManager,true);

$this->setHydrator($hydrator)
     ->setObject(new Policy());

如果我填写表格并保存到数据库,我可以看到数据正确存储在表中。如果我随后尝试将同一表单与实体水合,则没有任何 PolicyProduct 实体值被映射。但是,策略实体中的值已正确补充。

如果我转储出来$policyEntity->getPolicyProduct()我可以看到所有数据,这意味着实体正在正确保存和检索信息,问题似乎是当我尝试将实体数据提取到表单字段集时。

我希望这是有道理的,但如果没有,请告诉我,我会尽力澄清。

谢谢


以下是主要实体

政策

namespace Policy\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
* @ORM\Entity
* @ORM\Table(name="policy")
*/
class Policy {

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

    /**
    * @ORM\ManyToOne(targetEntity="Proposer\Entity\Proposer", inversedBy="policy")
    * @ORM\JoinColumn(name="proposer_id", referencedColumnName="id")
    *
    protected $proposer;

    /**
    * @ORM\ManyToOne(targetEntity="Product")
    * @ORM\JoinColumn(name="product_id", referencedColumnName="id", onDelete="RESTRICT")
    */
    protected $product;

    /**
    * @ORM\OneToOne(targetEntity="Policy\Entity\PolicyProduct")
    * @ORM\JoinColumn(name="policy_product_id", referencedColumnName="id")
    */
    protected $policyProduct;

    /**
    * @ORM\ManyToOne(targetEntity="PolicyStatus")
    * @ORM\JoinColumn(name="policy_status_id", referencedColumnName="id", onDelete="RESTRICT")
    */
    protected $policyStatus;

    /**
    * @ORM\Column(name="policyInception", type="date", nullable=true)
    */
    protected $policyInception;

    // Omitted getters and setters

}

政策产品

namespace Policy\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
* @ORM\Entity
* @ORM\Table(name="policy_product")
* @ORM\InheritanceType("JOINED")
* @ORM\DiscriminatorColumn(name="productDiscriminator", type="integer")
* @ORM\DiscriminatorMap({1 = "Tourers\Entity\TouringCaravan", 2 = "Statics\Entity\StaticCaravan", 3 = "Parkhomes\Entity\Parkhome"})
*/

class PolicyProduct {

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

    // Omitted getters and setters
}

TouringCaravan - PolicyProduct 继承表的示例

namespace Tourers\Entity;

use Doctrine\ORM\Mapping as ORM;
use Policy\Entity\PolicyProduct;

/**
* @ORM\Entity
* @ORM\Table(name="touring_caravan")
*/

class TouringCaravan extends PolicyProduct {

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

    /**
    * @ORM\OneToOne(targetEntity="Policy\Entity\Policy")
    * @ORM\JoinColumn(name="policy_id", referencedColumnName="id")
    */
    protected $policy;

    /**
    * @ORM\ManyToOne(targetEntity="TouringCaravanMake")
    * @ORM\JoinColumn(name="touring_caravan_make", referencedColumnName="id", onDelete="RESTRICT")
    */
    protected $caravanMake;

    /**
    * @ORM\Column(name="caravanModel", type="string", length=128, unique=false, nullable=false)
    */
    protected $caravanModel;

    ....
    Lots more columns specific to the TouringCaravan Entity

    // Omitted getters and setters
}
4

1 回答 1

0

看来您这里的实体太多了。如果我理解您想要做什么,则每项政策都与一个“类别”的产品相关联,这些产品将是 TouringCaravan、StaticCaravan 或 Parkhome。如果是这种情况,那么您的鉴别器列属于您的 Policy 实体,并且 PolicyProduct 实体可以消失。这是您想要执行的操作:

1) 进行此更改Policy\Entity\Policy

// ... //

/**
* @ORM\Entity
* @ORM\Table(name="policy")
* @ORM\InheritanceType("JOINED")
* @ORM\DiscriminatorColumn(name="policyProduct", type="integer")
* @ORM\DiscriminatorMap({1 = "Tourers\Entity\TouringCaravan", 2 = "Statics\Entity\StaticCaravan", 3 = "Parkhomes\Entity\Parkhome"})
*/
class Policy {

// ... //

并删除它:

/**
* @ORM\OneToOne(targetEntity="Policy\Entity\PolicyProduct")
* @ORM\JoinColumn(name="policy_product_id", referencedColumnName="id")
*/
protected $policyProduct;

1a) 当你在这里时,你需要为$proposerwith转义 DocBlock */

2) 删除Policy\Entity\PolicyProduct

Tourers\Entity\TouringCaravan3) 在和所有其他子实体中进行此更改:

// ... //

class TouringCaravan extends Policy {

// ... //

4)考虑重命名你的身份证。每个实体都有自己的 id,如果它们都被称为 $id,很容易忘记哪个是哪个。如果您的 Product 实体的 id 是$product_id,而您的 TouringCaravan 实体的 id 是$touring_caravan_id,以此类推,它们更容易识别。我在我的表和实体中为我的 id 分配了唯一的描述性名称,我发现如果我忘记制作一些映射语句,Doctrine 有时会为我建立联系。

5)。Tourers\Entity\TouringCaravan考虑从其他子实体中删除生成的子 id ,并让您的数据库在表中生成值。我发现当一个实体扩展另一个实体并且 JOIN 中有两个自动编号列时,Doctrine 不喜欢它。

您在这里要做的事情比您分享的要多得多(Proposer 实体和 PolicyStatus 实体),所以我不能说这些建议是否会解决您的所有问题,但这是一个开始。

与您的问题无关的另一个建议:

您可能会考虑将您的鉴别器列更改为字符串,而不是整数,并在那里记录产品的文本描述。否则,您将需要创建另一个实体或对数组进行硬编码以指示 1 = TouringCaravan、2 = StaticCaravan 和 3 = Parkhome。将文本记录在策略表中还可以让您更轻松地读取数据表或从单个实体创建索引视图(如果您发现需要)。

于 2014-04-25T21:55:09.110 回答