2

我正在使用JMSSerializer - 以及Doctrine構造函數 - 爲了反序列化發送的對象。當使用JMSSerializerBundle反序列化時如何使屬性「合併」或初始化

我的(簡化)實體如下。我忽略我認爲的代碼是沒用的:

Widget 
{ 
    protected $id; 

    /** 
    * @ORM\OneToMany(
    *  targetEntity="Belka\Iso50k1Bundle\Entity\VarSelection", 
    *  mappedBy="widget", 
    *  cascade={"persist", "remove", "detach", "merge"}) 
    * @Serializer\Groups({"o-all-getCWidget", "i-p2-create", "o-all-getWidget", "i-p3-create", "i-p2-editWidget"}) 
    * @Type("ArrayCollection<Belka\Iso50k1Bundle\Entity\VarSelection>") 
    */ 
    protected $varsSelection; 
} 


/** 
* @ORM\Entity() 
* 
* @ORM\InheritanceType("SINGLE_TABLE") 
* 
* @ORM\DiscriminatorColumn(
*  name="vartype", 
*  type="string") 
* 
* @ORM\DiscriminatorMap({ 
*  "PHY" = "PhyVarSelection" 
* }) 
* 
* @ORM\HasLifecycleCallbacks() 
*/ 
abstract class VarSelection 
{ 
    /** 
    * @Id 
    * @Column(type="integer") 
    * @GeneratedValue("SEQUENCE") 
    * @Serializer\groups({"o-all-getCWidget", "o-all-getWidget", "i-p2-editWidget"}) 
    */ 
protected $id; 
} 



class PhyVarSelection extends VarSelection 
{ 
    /** 
    * @var PhyVar 
    * 
    * @ORM\ManyToOne(
    *  targetEntity="Belka\Iso50k1Bundle\Entity\PhyVar", 
    *  cascade={"persist", "merge", "detach"}) 
    * 
    * @ORM\JoinColumn(
    *  name="phy_var_sel", 
    *  referencedColumnName="id", 
    *  nullable=false) 
    */ 
    protected $phyVar; 
} 

class PhyVar extends Variable 
{ 
    /** 
    * @ORM\Column(type="string") 
    * @ORM\Id 
    * 
    * @Serializer\Groups({"o-p2-getCMeters", "o-all-getWidget"}) 
    * @Assert\Regex("/(PHY)_\d+_\d+_\w+/") 
    */ 
    protected $id; 

    /** 
    * @ORM\Column(type="text", name="varname") 
    * @Serializer\Groups({"o-p2-getCMeters", "o-all-getWidget", "o-all-getCWidget"}) 
    */ 
    protected $varName; 

    ... 

} 

我嘗試反序列化表示Widget實體已經持續存在,與沿對象varselection數組用自己id規定 - 如果已經堅持 - 不和他們擁有id如果他們是新的並且被持續。

反序列化工作:

$context = new DeserializationContext(); 
$context->setGroups('i-p2-editWidget'); 
$data = $this->serializer->deserialize($content, $FQCN, 'json', $context); 

$data始終Widget::$varsSelection[]::$phyVar作爲初始化的代理類,只有id正確設置。我必須這樣做才能擁有這一切:

foreach ($data->getVarsSelection() as $varSel) { 
    $varSel->getVar(); 
} 

這是爲什麼?它如何能夠初始化?我不想花時間循環再次從DB獲取數據。

編輯

我已經添加了實體的域名,以便得到什麼,我反序列化 Domain of the entities

回答

0

的想法,我想通了,我自己的這種行爲方式及原因:

因爲我發送一個JSON如下所示:

{ 
    "id": <widgetID>, 
    "vars_selection": { 
    "id": <varSelectionID>, 
    "vartype": "PHY" 
    } 
} 

JMSSerializer的學說ObjectConstructor只是試圖發現只有兩個實體:通過執行以下行WidgetVarSelection

$object = $objectManager->find($metadata->name, $identifierList); 

換句話說:學說的EntityManager試圖找到其ID標識的實體。因此,請好好學習單元化的代理類。

據我所知,find不能指定水合模式。因此,有兩種處理方法:

  1. PhyVarSelection::$phyVar上指定fetch="EAGER"。相當昂貴,當我們不需要它時,
  2. 通過調用存儲庫替換ObjectConstructor並創建一個DQL,該DQL將正確設置EAGER選項。類似於$query->setFetchMode("PhyVarSelection", "phyVar", \Doctrine\ORM\Mapping\ClassMetadata::FETCH_EAGER);