我有一個大的時間試圖找出如何設置一個ManyToOne
- 使用Doctrine 2>OneToMany
關係,它仍然沒有工作...Symfony的2 - 多對一雙向關係的行爲
這裏是應用程序的行爲:
- 一個站點有
Page
小號 - 一個
User
可以在Page
這裏是我的實體(簡化):
評論實體:
**
* @ORM\Entity
* @ORM\Table(name="comment")
*/
class Comment {
/**
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* Many Comments have One User
*
* @ORM\ManyToOne(targetEntity="\Acme\UserBundle\Entity\User", inversedBy="comments")
*/
protected $user;
/**
* Many Comments have One Page
*
* @ORM\ManyToOne(targetEntity="\Acme\PageBundle\Entity\Page", inversedBy="comments")
*/
protected $page;
...
/**
* Set user
*
* @param \Acme\UserBundle\Entity\User $user
* @return Comment
*/
public function setUser(\Acme\UserBundle\Entity\User $user)
{
$this->user = $user;
return $this;
}
/**
* Set page
*
* @param \Acme\PageBundle\Entity\Page $page
* @return Comment
*/
public function setPage(\Acme\PageBundle\Entity\Page $page)
{
$this->page = $page;
return $this;
}
用戶實體:
/**
* @ORM\Entity
* @ORM\Table(name="fos_user")
*/
class User extends BaseUser
{
/**
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* The User create the Comment so he's supposed to be the owner of this relationship
* However, Doctrine doc says: "The many side of OneToMany/ManyToOne bidirectional relationships must be the owning
* side", so Comment is the owner
*
* One User can write Many Comments
*
* @ORM\OneToMany(targetEntity="Acme\CommentBundle\Entity\Comment", mappedBy="user")
*/
protected $comments;
...
/**
* Get Comments
*
* @return \Doctrine\Common\Collections\Collection
*/
public function getComments() {
return $this->comments ?: $this->comments = new ArrayCollection();
}
頁實體:
/**
* @ORM\Entity
* @ORM\Table(name="page")
*/
class Page
{
/**
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* One Page can have Many Comments
* Owner is Comment
*
* @ORM\OneToMany(targetEntity="\Acme\CommentBundle\Entity\Comment", mappedBy="page")
*/
protected $comments;
...
/**
* @return \Doctrine\Common\Collections\Collection
*/
public function getComments(){
return $this->comments ?: $this->comments = new ArrayCollection();
}
我希望有一個雙向關係能夠獲得的收藏來自Page
或來自User
的個(使用getComments()
)。
我的問題是,當我嘗試保存新Comment
,我得到一個錯誤,說教義是無法創建一個Page
實體。我想這是因爲它沒有找到Page
(但它應該),所以它試圖創建一個新的Page
實體,以便稍後將其鏈接到我嘗試創建的Comment
實體。
這裏是我的控制器方法來創建一個Comment
:
public function createAction()
{
$user = $this->getUser();
$page = $this->getPage();
$comment = new EntityComment();
$form = $this->createForm(new CommentType(), $comment);
if ($this->getRequest()->getMethod() === 'POST') {
$form->bind($this->getRequest());
if ($form->isValid()) {
$em = $this->getDoctrine()->getManager();
$comment->setPage($page);
$comment->setUser($user);
$em->persist($comment);
$em->flush();
return $this->redirect($this->generateUrl('acme_comment_listing'));
}
}
return $this->render('AcmeCommentBundle:Default:create.html.twig', array(
'form' => $form->createView()
));
}
我不明白爲什麼會這樣。我已經在此控制器中檢查了我的Page
對象(由$this->getPage()
返回 - 返回存儲在會話中的對象),並且它是存在的有效Page
實體(我也在數據庫中檢查過)。
我不知道現在該做什麼,我無法找到有同樣的問題:(
這是確切的錯誤消息我的人:
一個新的實體被發現通過沒有配置爲 級聯關係 「的Acme \ CommentBundle \實體\評論#頁」堅持實體操作: 的Acme \ PageBundle \實體\頁@ 000000005d8a1f2000000000753399d4爲了解決 這個問題:無論是顯式調用的EntityManager#堅持()在這個 unkno wn實體或配置級聯在 映射中堅持這個關聯,例如@ManyToOne(..,cascade = {「persist」})。如果您不能 找出哪個實體導致問題實現 'Acme \ PageBundle \ Entity \ Page #__ toString()'以獲得線索。
但我不想添加cascade={"persist"}
,因爲我不想在級聯上創建頁面,而只是鏈接現有的頁面。
UPDATE1:
如果我取前設置它的頁面,它的工作。但我仍然不知道爲什麼我應該。
public function createAction()
{
$user = $this->getUser();
$page = $this->getPage();
// Fetch the page from the repository
$page = $this->getDoctrine()->getRepository('AcmePageBundle:page')->findOneBy(array(
'id' => $page->getId()
));
$comment = new EntityComment();
// Set the relation ManyToOne
$comment->setPage($page);
$comment->setUser($user);
$form = $this->createForm(new CommentType(), $comment);
if ($this->getRequest()->getMethod() === 'POST') {
$form->bind($this->getRequest());
if ($form->isValid()) {
$em = $this->getDoctrine()->getManager();
$em->persist($comment);
$em->flush();
return $this->redirect($this->generateUrl('acme_comment_listing'));
}
}
return $this->render('AcmeCommentBundle:Default:create.html.twig', array(
'form' => $form->createView()
));
}
UPDATE2:
我已經結束了存儲在會話(而不是完整的對象),我認爲這是考慮到一個事實,我不會有一個更好的主意了PAGE_ID使用會話來存儲,但只是ID。我也期待Doctrine在檢索Page
實體時緩存查詢。
但有人能解釋爲什麼我不能使用會話中的Page
實體嗎?這是我是如何設置會話:
$pages = $site->getPages(); // return doctrine collection
if (!$pages->isEmpty()) {
// Set the first page of the collection in session
$session = $request->getSession();
$session->set('page', $pages->first());
}
更多信息,你是不是缺少在'Comment'實體'page_id'屬性? – cheesemacfly 2013-02-13 01:33:22
我不應該在'Comment'實體中定義一個'page_id'屬性,因爲已經定義了關係'ManyToOne'(這是爲了解決這個問題)。在我的數據庫模式中,我在'Comment'表中包含了正確的字段:'user_id'和'page_id' – maxwell2022 2013-02-13 02:12:49
但是你需要添加'@ORM \ JoinColumn(name =「page_id」,referencedColumnName =「id」)''你的@ORM \ ManyToOne'。或者我錯過了什麼? – cheesemacfly 2013-02-13 02:33:38