2017-09-16 41 views
0

我有一個與Symfony3/Doctrine2 Rest Api一起工作的Angular4應用程序。堅持在已經存在的情況下創建新的實體(Ont-To-Many多對一關係)

無論在角和Symfony的,我有這些實體:

  • TableNode
  • 節點

表和節點之間的關係是:

表( OneToMany)TableNode(ManyToOne)節點

什麼是「ManyToMany」與屬性的關係。

在Angular應用程序中,我創建了一個新表(形成一個TableModel,它與Symfony應用程序中的Table實體具有完全相同的屬性)。 該表包含來自Api的幾個節點實體(因此它們已經存在於我的數據庫中)。

我想要的是創建一個新的表,其中包含新的TableNode實體,每個TableNode應該包含現有的節點實體。

當我要保存的數據庫內我的桌子,我把我的API,可以通過認沽動作:

/** 
* PUT Route annotation 
* @Put("/tables") 
*/ 
public function putTableAction(Request $request) 
{ 
    $em   = $this->getDoctrine()->getManager('psi_db'); 
    $serializer = $this->container->get('jms_serializer'); 
    $dataJson = $request->query->get('table'); 
    $table  = $serializer->deserialize($dataJson, Table::class, 'json'); 

    // Here, my $table has no id (that's ok), the TableNode subentity has no id (ok) and my Node subentity already have an id (because they come from the db) 

    $em->persist($table); 

    // Here, my $table has a new id (ok), my TableNode has a new id (ok) BUT my Node subentity have a NEW id, so it will be duplicated 

    $em->flush(); 

    $view = $this->view(); 
    $view->setData($table); 
    return $this->handleView($view); 
} 

我試着使用$ EM->合併($表),而不是$ IM-> persist($ table)和我的節點子實體保持自己的id(所以它們不能在flush內複製),但table和tableNode沒有id(null)並且沒有持久化。

我發現的唯一的解決辦法是遍歷TableNode實體,從數據庫中檢索節點實體,並做了tableNode-> setNode:

$tns = $table->getTableNodes(); 
foreach ($tns as $tn) { 
    $nodeId = $tn->getNode()->getId(); 
    $dbNode = $nodeRepo->find($nodeId); 
    $tn->setNode($dbNode); 
} 

但因爲我做一個分貝這不是一個很好的解決方案在循環和表中搜索可能包含超過一百個TableNode/Node,因此可能需要大量資源。

有沒有人有更清潔的解決方案? 謝謝。

編輯:添加類

表:

/** 
* Table_ 
* Doctrine "Table" is a reserved name, so we call it Table_ 
* 
* @ORM\Table(name="psi_table") 
* @ORM\Entity(repositoryClass="AppBundle\Repository\Table_Repository") 
* 
* @ExclusionPolicy("all") 
*/ 
class Table_ 
{ 
    public function __construct() 
    { 
     $this->tNodes = new ArrayCollection(); 
    } 

    /** 
    * @var integer 
    * 
    * @ORM\Column(name="id", type="integer") 
    * @ORM\Id 
    * @ORM\GeneratedValue(strategy="AUTO") 
    * 
    * @Expose 
    */ 
    private $id; 

    /** 
    * @var string 
    * 
    * @ORM\Column(name="name", type="string", length=255, nullable=true) 
    * 
    * @Expose 
    */ 
    private $name; 

    /** 
    * @var \stdClass 
    * 
    * @ORM\Column(name="author", type="object", nullable=true) 
    * 
    * @Expose 
    */ 
    private $author; 

    /** 
    * @var \stdClass 
    * 
    * @ORM\OneToMany(targetEntity="AppBundle\Entity\TableNode", mappedBy="table", cascade={"persist"}) 
    * 
    * @Expose 
    * @Type("ArrayCollection<AppBundle\Entity\TableNode>") 
    * @SerializedName("tNodes") 
    */ 
    private $tNodes; 
} 

TableNode:

/** 
* TableNode 
* 
* @ORM\Table(name="psi_table_node") 
* @ORM\Entity(repositoryClass="AppBundle\Repository\TableNodeRepository") 
* 
* @ExclusionPolicy("all") 
*/ 
class TableNode 
{ 
    public function __construct($table = null, $node = null, $position = null) 
    { 
     if($table) $this->table = $table; 
     if($node) $this->node = $node; 
     if($position) $this->position = $position; 
    } 

    /** 
    * @var integer 
    * 
    * @ORM\Column(name="id", type="integer") 
    * @ORM\Id 
    * @ORM\GeneratedValue(strategy="AUTO") 
    * 
    * @Expose 
    */ 
    private $id; 

    /** 
    * @var integer 
    * 
    * @ORM\Column(name="position", type="integer") 
    * 
    * @Expose 
    */ 
    private $position; 

    /** 
    * @var string 
    * 
    * @ORM\Column(name="groupSocio", type="string", nullable=true) 
    * 
    * @Expose 
    * @SerializedName("groupSocio") 
    */ 
    private $groupSocio; 

    /** 
    * @ORM\ManyToOne(targetEntity="AppBundle\Entity\Table_", inversedBy="tNodes", cascade={"persist"}) 
    * @ORM\JoinColumn(nullable=false) 
    * 
    * @Expose 
    * @Type("AppBundle\Entity\Table_") 
    */ 
    private $table; 

    /** 
    * @ORM\ManyToOne(targetEntity="AppBundle\Entity\Node", inversedBy="tables", cascade={"persist", "merge"}) 
    * @ORM\JoinColumn(nullable=false) 
    * 
    * @Expose 
    * @Type("AppBundle\Entity\Node") 
    */ 
    private $node; 
} 

節點:

/** 
* TableNode 
* 
* @ORM\Table(name="psi_table_node") 
* @ORM\Entity(repositoryClass="AppBundle\Repository\TableNodeRepository") 
* 
* @ExclusionPolicy("all") 
*/ 
class TableNode 
{ 
    public function __construct($table = null, $node = null, $position = null) 
    { 
     if($table) $this->table = $table; 
     if($node) $this->node = $node; 
     if($position) $this->position = $position; 
    } 

    /** 
    * @var integer 
    * 
    * @ORM\Column(name="id", type="integer") 
    * @ORM\Id 
    * @ORM\GeneratedValue(strategy="AUTO") 
    * 
    * @Expose 
    */ 
    private $id; 

    /** 
    * @var integer 
    * 
    * @ORM\Column(name="position", type="integer") 
    * 
    * @Expose 
    */ 
    private $position; 

    /** 
    * @var string 
    * 
    * @ORM\Column(name="groupSocio", type="string", nullable=true) 
    * 
    * @Expose 
    * @SerializedName("groupSocio") 
    */ 
    private $groupSocio; 

    /** 
    * @ORM\ManyToOne(targetEntity="AppBundle\Entity\Table_", inversedBy="tNodes", cascade={"persist"}) 
    * @ORM\JoinColumn(nullable=false) 
    * 
    * @Expose 
    * @Type("AppBundle\Entity\Table_") 
    */ 
    private $table; 

    /** 
    * @ORM\ManyToOne(targetEntity="AppBundle\Entity\Node", inversedBy="tables", cascade={"persist", "merge"}) 
    * @ORM\JoinColumn(nullable=false) 
    * 
    * @Expose 
    * @Type("AppBundle\Entity\Node") 
    */ 
    private $node; 
} 

提交的數據(例如):

{"tNodes":[{"id":0,"position":0,"groupSocio":"group1","node":{"id":683,"frontId":"1502726228584","level":"synusy","repository":"baseveg","name":"A synusy from my Angular app!","geoJson":{"type":"FeatureCollection","features":[{"type":"Feature","properties":[],"geometry":{"type":"Point","coordinates":[-10.0634765625,42.0982224112]}}]},"lft":1,"lvl":0,"rgt":2,"children":[{"id":684,"frontId":"1502726228586","level":"idiotaxon","repository":"baseflor","name":"poa annua","coef":"1","geoJson":{"type":"FeatureCollection","features":[{"type":"Feature","properties":[],"geometry":{"type":"Point","coordinates":[-10.0634765625,42.0982224112]}}]},"lft":1,"lvl":0,"rgt":2,"validations":[{"id":171,"repository":"baseflor","repositoryIdTaxo":"7075","repositoryIdNomen":"50284","inputName":"poa annua","validatedName":"Poa annua L."}]}],"validations":[]}}]} 
+0

請向我們展示JMSSerializer註釋類Table,TableNode和Node中的註釋。 同時顯示您提交的請求URL的示例(或$ dataJson的值) –

+0

我編輯了帖子並添加了詢問信息。 Thx –

+0

你有一個錯字 - 你添加了兩次TableNode,並沒有添加Node類。 –

回答

0

目的putTableAction是:

  • 創建的新實例Table_
  • 創建TableNode
  • 的新實例
  • 什麼也不做日節點

這意味着:

1.You不需要提交節點的任何細節。 編號場就夠了:

{"tNodes":[{"id":0,"position":0,"groupSocio":"group1","nodeId": 683}]} 

2.You可以多一個字段添加到TableNode,稱爲$ NODEID,並與DB 「節點」 字段映射。這個字段的目的是爲了簡化反序列化,在所有其他地方你可以使用$ node字段。

/** 
* @var integer 
* 
* @ORM\Column(name="node", type="integer") 
* 
* @Expose 
*/ 
private $nodeId; 
相關問題