【发布时间】:2017-09-16 09:03:59
【问题描述】:
我有一个使用 Symfony3/Doctrine2 Rest Api 的 Angular4 应用程序。
在 Angular 和 Symfony 中,我都有这些实体:
- 表
- 表节点
- 节点
Table和Node的关系是:
表(OneToMany)TableNode(多对一)节点
什么是与属性的“多对多”关系。
在 Angular 应用程序中,我创建了一个新表(形成一个与 Symfony 应用程序中的表实体具有完全相同属性的 TableModel)。 此表包含几个来自 Api 的 Node 实体(因此它们已经存在于我的数据库中)。
我想要的是创建一个包含新 TableNode 实体的新表,并且每个 TableNode 都应该包含现有的 Node 实体。
当我想将我的表保存在数据库中时,我通过 Put 操作调用我的 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->merge($table) 而不是 $em->persist($table) 并且我的节点子实体保留了自己的 ID(因此它们可能不会在刷新中重复)但是表和tableNode 没有 id (null) 并且没有持久化。
我找到的唯一解决方案是遍历 TableNode 实体,从数据库中检索 Node 实体并执行 tableNode->setNode :
$tns = $table->getTableNodes();
foreach ($tns as $tn) {
$nodeId = $tn->getNode()->getId();
$dbNode = $nodeRepo->find($nodeId);
$tn->setNode($dbNode);
}
但这不是一个好的解决方案,因为我在循环中进行 db 搜索,并且一个表可能包含一百多个 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
*
* @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":[]}}]}
【问题讨论】:
-
请向我们展示 Table、TableNode 和 Node 类中的 JMSSerializer 注释。还显示您提交的请求 URL 示例(或 $dataJson 的值)
-
我编辑了帖子并添加了询问信息。谢谢
-
你打错了 - 你添加了两次 TableNode,并没有添加 Node 类。