Symfony2/Doctrine:如何将具有 OneToMany 的实体重新保存为级联新行
首先,这个问题类似于 如何将实体重新保存为 Doctrine 2 中的另一行
区别在于,我试图将数据保存在具有 OneToMany 关系的实体中。我想将实体重新保存为父实体中的新行(在“一”侧),然后将其保存为每个后续子实体中的新行(在“多”侧)。
为了简单起见,我使用了一个非常简单的例子,即有很多学生的教室。
所以我可能有 id=1 的 ClassroomA,它有 5 个学生(id 1 到 5)。我想知道如何在 Doctrine2 中获取该实体并将其重新保存到数据库(在潜在的数据更改之后),所有这些都具有新的 ID,并且在持久/刷新期间原始行保持不变。
让我们首先定义我们的学说实体。
课堂实体:
namespace Acme\TestBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
/**
* @ORM\Entity
* @ORM\Table(name="classroom")
*/
class Classroom
{
/**
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @ORM\Column(type="string", length=255)
*/
private $miscVars;
/**
* @ORM\OneToMany(targetEntity="Pupil", mappedBy="classroom")
*/
protected $pupils;
public function __construct()
{
$this->pupils = new ArrayCollection();
}
// ========== GENERATED GETTER/SETTER FUNCTIONS BELOW ============
}
学生实体:
namespace Acme\TestBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
/**
* @ORM\Entity
* @ORM\Table(name="pupil")
*/
class Pupil
{
/**
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @ORM\Column(type="string", length=255)
*/
private $moreVars;
/**
* @ORM\ManyToOne(targetEntity="Classroom", inversedBy="pupils")
* @ORM\JoinColumn(name="classroom_id", referencedColumnName="id")
*/
protected $classroom;
// ========== GENERATED FUNCTIONS BELOW ============
}
以及我们的通用操作函数:
public function someAction(Request $request, $id)
{
$em = $this->getDoctrine()->getEntityManager();
$classroom = $em->find('AcmeTestBundle:Classroom', $id);
$form = $this->createForm(new ClassroomType(), $classroom);
if ('POST' === $request->getMethod()) {
$form->bindRequest($request);
if ($form->isValid()) {
// Normally you would do the following:
$em->persist($classroom);
$em->flush();
// But how do I create a new row with a new ID
// Including new rows for the Many side of the relationship
// ... other code goes here.
}
}
return $this->render('AcmeTestBundle:Default:index.html.twig');
}
我尝试使用克隆,但仅使用新 ID 保存父关系(在我们的示例中为课堂),而儿童数据(学生)则根据原始数据进行更新身份证。
预先感谢您的任何帮助。
Firstly, this question is similar to How to re-save the entity as another row in Doctrine 2
The difference is that I'm trying to save the data within an entity that has a OneToMany relationship. I'd like to re-save the entity as a new row in the parent entity (on the "one" side) and then as new rows in each subsequent child (on the "many" side).
I've used a pretty simple example of a Classroom having many Pupils to keep it simple.
So me might have ClassroomA with id=1 and it has 5 pupils (ids 1 through 5). I'd like to know how I could, within Doctrine2, take that Entity and re-save it to the database (after potential data changes) all with new IDs throughout and the original rows being untouched during the persist/flush.
Lets first define our Doctrine Entities.
The Classroom Entity:
namespace Acme\TestBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
/**
* @ORM\Entity
* @ORM\Table(name="classroom")
*/
class Classroom
{
/**
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @ORM\Column(type="string", length=255)
*/
private $miscVars;
/**
* @ORM\OneToMany(targetEntity="Pupil", mappedBy="classroom")
*/
protected $pupils;
public function __construct()
{
$this->pupils = new ArrayCollection();
}
// ========== GENERATED GETTER/SETTER FUNCTIONS BELOW ============
}
The Pupil Entity:
namespace Acme\TestBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
/**
* @ORM\Entity
* @ORM\Table(name="pupil")
*/
class Pupil
{
/**
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @ORM\Column(type="string", length=255)
*/
private $moreVars;
/**
* @ORM\ManyToOne(targetEntity="Classroom", inversedBy="pupils")
* @ORM\JoinColumn(name="classroom_id", referencedColumnName="id")
*/
protected $classroom;
// ========== GENERATED FUNCTIONS BELOW ============
}
And our generic Action function:
public function someAction(Request $request, $id)
{
$em = $this->getDoctrine()->getEntityManager();
$classroom = $em->find('AcmeTestBundle:Classroom', $id);
$form = $this->createForm(new ClassroomType(), $classroom);
if ('POST' === $request->getMethod()) {
$form->bindRequest($request);
if ($form->isValid()) {
// Normally you would do the following:
$em->persist($classroom);
$em->flush();
// But how do I create a new row with a new ID
// Including new rows for the Many side of the relationship
// ... other code goes here.
}
}
return $this->render('AcmeTestBundle:Default:index.html.twig');
}
I've tried using clone but that only saved the parent relationship (Classroom in our example) with a fresh ID, while the children data (Pupils) was updated against the original IDs.
Thanks in advance to any assistance.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
克隆
的事情是......如果您使用的是 Doctrine >= 2.0.2,您可以实现自己的自定义 __clone() 方法:
注意:在 Doctrine 2.0.2 之前,您无法在实体中实现
__clone()
方法作为生成的代理类实现其自己的__clone()
,它不会检查或调用parent::__clone()
。因此,您必须为此创建一个单独的方法,例如clonePupils()
(在Classroom
中),并在克隆实体后调用该方法。无论哪种方式,您都可以在__clone()
或clonePupils()
方法中使用相同的代码。当您克隆父类时,此函数也将创建一个充满子对象克隆的新集合。
您可能希望在您的
$pupils
集合上级联持久化以使持久化更容易,例如The thing with
clone
is...If you are using Doctrine >= 2.0.2, you can implement your own custom __clone() method:
NOTE: before Doctrine 2.0.2 you cannot implement a
__clone()
method in your entity as the generated proxy class implements its own__clone()
which does not check for or callparent::__clone()
. So you'll have to make a separate method for that likeclonePupils()
(inClassroom
) instead and call that after you clone the entity. Either way, you can use the same code inside your__clone()
orclonePupils()
methods.When you clone your parent class, this function will create a new collection full of child object clones as well.
You'll probably want to cascade persist on your
$pupils
collection to make persisting easier, eg我这样做了并且效果很好。
在克隆实体内部,我们有神奇的__clone()。在那里我们也不会忘记我们的一对多。
在某个地方克隆它:
I did it like this and it works fine.
Inside cloned Entity we have magic __clone(). There we also don't forget our one-to-many.
Somewhere just clone it:
我这样做:
I do this: