我的symfony代码有问题:我的存储库更新方法
/**
* @param MenuModel $menu
* @return MenuEntity|MenuModel
* @throws RepositoryException
*/
public function updateMenu(MenuModel $menu)
{
try {
$transformedMenu = $this->menuTransformer->transform($menu);
$transformedMenu = $this->getEntityManager()->merge($transformedMenu);
$this->getEntityManager()->flush($transformedMenu);
$this->getEntityManager()->detach($transformedMenu);
return $this->menuTransformer->transform($transformedMenu);
} catch (\Exception $e) {
throw new RepositoryException($e->getMessage() . ' in ' . $e->getFile() . ':' . $e->getLine());
}
}
我的元素实体:
/**
* Element.
*
* @ORM\HasLifecycleCallbacks
* @ORM\Table(name="element")
* @ORM\ChangeTrackingPolicy("DEFERRED_EXPLICIT")
* @ORM\Entity(repositoryClass="CP\API\Repository\ElementRepository")
*/
class Element extends \CP\RestBundle\Model\Element
{
use Traits\SystemObjectTrait;
use Traits\ChannelsTrait;
use Traits\PropertiesTrait;
use Traits\WorkflowTrait;
/**
* @ORM\ManyToOne(targetEntity="Menu", inversedBy="contents")
* @ORM\JoinColumn(name="menu_id", referencedColumnName="id")
*/
protected $menu;
/**
* Element constructor.
*/
public function __construct()
{
parent::__construct();
}
/**
* @param int $id
*
* @return Element
*/
public function setId(int $id): self
{
$this->id = $id;
return $this;
}
/**
* Update publication by modification when empty
* Update status according to publication, unpublication and archiving
*
* @ORM\PrePersist()
*/
protected function prePersist()
{
$this->updatePublication();
$this->updateStatus();
}
/**
* Update publication by modification when empty
* Update status according to publication, unpublication and archiving
*
* @ORM\PreUpdate()
*/
public function preUpdate()
{
$this->updatePublication();
$this->updateStatus();
}
/**
* Increases object version
*/
public function increaseVersion()
{
++$this->version;
}
/**
* @return mixed
*/
public function getMenu()
{
return $this->menu;
}
/**
* @param mixed $menu
*/
public function setMenu($menu): void
{
$this->menu = $menu;
}
}
我的菜单实体
<?php
namespace CP\API\Entity;
use CP\API\Entity\Traits\TimestampableTrait;
use CP\Model\Configuration;
use CP\Model\Content;
use CP\Model\Language;
use CP\Model\MenuTranslation;
use CP\RestBundle\Model\Locator;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
/**
* @ORM\HasLifecycleCallbacks()
* @ORM\Table(name="custom_menu")
* @ORM\Entity(repositoryClass="CP\API\Repository\MenuRepository")
*/
class Menu
{
use TimestampableTrait;
/**
* @var int
*
* @ORM\Id()
* @ORM\Column(type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* @ORM\OneToMany(targetEntity="CP\API\Entity\Element",mappedBy="menu",cascade={"persist"})
*/
protected $contents;
public function __construct(Menu $parent = null)
{
$dateTime = new \DateTime();
$this->creation = $dateTime;
$this->modification === null && $this->setModification($dateTime);
$this->contents = new ArrayCollection();
}
/**
* @return int
*/
public function getId(): int
{
return $this->id;
}
/**
* @param int $id
*/
public function setId(int $id): void
{
$this->id = $id;
}
/**
* @return ArrayCollection
*/
public function getContents(): ArrayCollection
{
return $this->contents;
}
/**
* @param ArrayCollection $contents
*/
public function setContents(ArrayCollection $contents): void
{
$this->contents = $contents;
}
/**
* @param Element $element
* @return $this
*/
public function addContent(Element $element): self
{
if (!$this->contents->contains($element)) {
$this->contents[] = $element;
$element->setMenu($this);
}
return $this;
}
/**
* @param Element $element
* @return $this
*/
public function removeContent(Element $element): self
{
if ($this->contents->contains($element)) {
$this->contents->removeElement($element);
if ($element->getMenu() === $this) {
$element->setMenu(null);
}
}
return $this;
}
}
我的菜单型号
<?php
namespace CP\Model;
use CP\RestBundle\Model\Element;
use CP\RestBundle\Model\Locator;
use CP\RestBundle\Model\Product;
use CP\RestBundle\Model\Traits\TimestampableTrait;
class Menu extends BaseModel
{
/** @var Content[] */
protected $content;
/**
* @return array|null
*/
public function getContent(): ?array
{
return $this->content;
}
/**
* @param Content[] $content
*/
public function setContent(array $content): void
{
$this->content = $content;
}
}
我的从模型到实体的转换器
public function transform($object)
{
if ($object instanceof Menu) {
$menuData = new MenuEntity();
if ($object->getId())
$menuData->setId($object->getId());
if ($object->getContent() instanceof Content) {
$contentEntity = new ContentEntity();
$content = $object->getContent();
$contentEntity->setId($content->getId());
$menuData->addContent($this->attachToEntityManager($contentEntity));
}
return $menuData;
}
private function attachToEntityManager($object)
{
try {
$attachedObject = $this->entityManager->merge($object);
return $attachedObject;
} catch (ORMException $e) {
throw new ModelTransformationException(sprintf('Model transformation error, object could not be attached to Entity Manager: %s in %s',
$e->getMessage(), $e->getFile() . ':' . $e->getLine()));
}
}
[当我尝试保存数据时,我没有任何错误,但是在数据库上没有任何更改,即元素实体没有从关系中分配menu_id。我不知道怎么了,也许我不知道如何使用和保存OneToMany关系。
任何想法?
您能给我们更多代码执行情况的信息吗? MenuEntity的构造函数很奇怪,不使用$ parent,不使用布尔比较。为什么需要使用EntityManager的分离和合并方法-麦斯基
是的,我在这里看不到使用分离和/或合并的意义。通常,使用OneToMany关系时,您可以使用实体管理器并保持两个关系(刷新),并且您应该拥有一个具有OneToMany关系的实体。
我希望这会有所帮助,特别是这部分:https://symfony.com/doc/current/doctrine/associations.html#saving-related-entities
示例:
// relates this product to the category
$product->setCategory($category);
$entityManager = $this->getDoctrine()->getManager();
$entityManager->persist($category);
$entityManager->persist($product);
$entityManager->flush();