【问题标题】:ZF2 + Doctrine2 Class Table Inherritence ExcrationZF2+Doctrine类表继承排泄
【发布时间】:2013-11-18 11:56:57
【问题描述】:

我在让我的学说实体提取到我的 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 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 作为每个字段集的水合器。然后我在每个字段集的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
}

【问题讨论】:

    标签: php doctrine-orm zend-framework2 zend-form class-table-inheritance


    【解决方案1】:

    您的实体似乎太多了。如果我了解您要做什么,则每项政策都与一个“类别”的产品相关联,这些产品将是 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) 当您在这里时,您需要使用 */ 转义 $proposer 的 DocBlock。

    2) 删除Policy\Entity\PolicyProduct

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

    // ... //
    
    class TouringCaravan extends Policy {
    
    // ... //
    

    4) 考虑重命名您的 id。每个实体都有自己的 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。将文本记录在策略表中还可以让您更轻松地读取数据表或根据需要从单个实体创建索引视图。

    【讨论】:

    • @mikeaag 你真的尝试过 jcropp 的建议吗?很高兴在这里提供一些反馈......
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-10
    • 1970-01-01
    • 1970-01-01
    • 2015-07-01
    • 1970-01-01
    • 2023-01-26
    相关资源
    最近更新 更多