【发布时间】:2014-06-10 15:44:57
【问题描述】:
这是一个非常非常简单的行为,但是我找不到用教义实现它的方法。我将解释它仅使用两个实体来降低复杂性。
有两个相关的实体(作者和书籍),例如“一个作者拥有零个或多个书籍”和“一本书由零个或一个作者拥有”,我正在尝试取消作者与他的一个作者之间的关系书籍(来自作者方面),期望数据库中的 book.author_id 字段设置为空。
实体定义如下:
作者
/**
* Author
*
* @ORM\Table()
* @ORM\Entity(repositoryClass="Poc\PocBundle\Entity\AuthorRepository")
*/
class Author
{
/**
* @var integer
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @var string
*
* @ORM\Column(name="name", type="string", length=255)
*/
private $name;
/**
* Get id
*
* @return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set name
*
* @param string $name
* @return Author
*/
public function setName($name)
{
$this->name = $name;
return $this;
}
/**
* Get name
*
* @return string
*/
public function getName()
{
return $this->name;
}
/**
* @ORM\OneToMany(targetEntity="Book", mappedBy="author", cascade={"persist", "remove"})
*/
private $books;
public function __construct()
{
$this->products = new ArrayCollection();
}
/**
* Add books
*
* @param \Poc\PocBundle\Entity\Book $books
* @return Author
*/
public function addBook(\Poc\PocBundle\Entity\Book $books)
{
$this->books[] = $books;
return $this;
}
/**
* Remove books
*
* @param \Poc\PocBundle\Entity\Book $books
*/
public function removeBook(\Poc\PocBundle\Entity\Book $books)
{
$this->books->removeElement($books);
}
/**
* Get books
*
* @return \Doctrine\Common\Collections\Collection
*/
public function getBooks()
{
return $this->books;
}
}
图书
/**
* Book
*
* @ORM\Table()
* @ORM\Entity(repositoryClass="Poc\PocBundle\Entity\BookRepository")
*/
class Book
{
/**
* @var integer
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @var string
*
* @ORM\Column(name="name", type="string", length=255)
*/
private $name;
/**
* Get id
*
* @return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set name
*
* @param string $name
* @return Book
*/
public function setName($name)
{
$this->name = $name;
return $this;
}
/**
* Get name
*
* @return string
*/
public function getName()
{
return $this->name;
}
/**
* @ORM\ManyToOne(targetEntity="Author", inversedBy="books")
* @ORM\JoinColumn(name="author_id", referencedColumnName="id", onDelete="SET NULL")
*/
protected $author;
/**
* Set author
*
* @param \Poc\PocBundle\Entity\Author $author
* @return Book
*/
public function setAuthor(\Poc\PocBundle\Entity\Author $author = null)
{
$this->author = $author;
return $this;
}
/**
* Get author
*
* @return \Poc\PocBundle\Entity\Author
*/
public function getAuthor()
{
return $this->author;
}
}
在主控制器中,我执行以下操作。
检索作者
检索此作者拥有的图书
从作者手中删除图书
坚持作者和刷新
检索书
获取作者...
作者保持不变。在数据库中,该记录的字段 book.author_id 没有按预期设置为 NULL,但仍与作者相关。
控制器代码:
$Book = $this->getDoctrine()
->getRepository('PocPocBundle:Book')
->find('1');
$Author = $this->getDoctrine()
->getRepository('PocPocBundle:Author')
->find('1');
$Author->removeBook($Book);
$em = $this->getDoctrine()->getManager();
$em->persist($Author);
$em->flush();
echo "<pre>";
$Book = $this->getDoctrine()
->getRepository('PocPocBundle:Book')
->find('1');
\Doctrine\Common\Util\Debug::dump($Book);
die;
...以及输出
object(stdClass)[286]
public '__CLASS__' => string 'Poc\PocBundle\Entity\Book' (length=25)
public 'id' => int 1
public 'name' => string 'El Quijote' (length=10)
public 'author' =>
object(stdClass)[293]
public '__CLASS__' => string 'Poc\PocBundle\Entity\Author' (length=27)
public '__IS_PROXY__' => boolean true
public '__PROXY_INITIALIZED__' => boolean true
public 'id' => int 1
public 'name' => string 'Cervantes' (length=9)
public 'books' => string 'Array(1)' (length=8)
在实体 Book (id=1) 的输出中,我们可以看到这本书仍然与作者相关。
当然,我遗漏了一些东西,但我找不到差距在哪里。
【问题讨论】:
-
既然要删除,为什么还要坚持?最好在顶部定义
$em = $this->getDoctrine()->getManager();,然后基于$em应用所有更改,最后你只是$em->flush();我认为单独选择书和作者然后删除不是一个好主意;你如何确保id为1的作者与id为1的书相关?! -
在这个例子中,为了澄清行为,我将书和作者分开。真正的应用程序不会这样做,但我已将问题简化为此示例以简化它。
-
那如果要删除为什么还要坚持呢?此外,在您编辑后,您需要通过
$em->refresh($Book);刷新实体,然后您可以打印所有新的更新值
标签: php symfony doctrine-orm one-to-many