学说 Symfony2 坚持与现有的关联实体

Posted

技术标签:

【中文标题】学说 Symfony2 坚持与现有的关联实体【英文标题】:Doctrine Symfony2 persist association entity with existing one 【发布时间】:2017-05-20 10:02:14 【问题描述】:

我有两个实体 Product 和 Category 关联类型为 ManyToOne,假设我想创建一个新产品并且我已经知道它的类别(意味着我知道 ID 类别)

类产品

/**
 * @ORM\Entity
 * @ORM\Table(name="product")
 */
class Product

    /**
     * @ORM\Column(type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @ORM\Column(type="string", length=100)
     */
    private $name;

    /**
     * @ORM\ManyToOne(targetEntity="Category")
     * @ORM\JoinColumn(name="category_id", referencedColumnName="id")
     */
    private $category;

课程类别

/**
 * @ORM\Entity
 * @ORM\Table(name="category")
 */
class Category

    /**
     * @ORM\Column(type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

SCRNARIO:创建新产品,假设我知道 ID 类别,所以我们不需要使用 Category Entity 的 find 方法来获取它(让事情变得更快)

$em = $this->get('doctrine')->getManager();
$category = new Category();
$category->setId(12);
$product = new Product();
$product->setName('product 1');
$product->setCategory($category);
$em->persist($product);
$em->flush();

上面的代码不工作它会产生一个异常:

通过关系发现了一个新实体 'AOBundle\Entity\Product#category' 未配置为级联 实体的持久化操作: AOBundle\Entity\Category@0000000049a05dc500000000723a1be6。解决 这个问题:要么显式调用 EntityManager#persist() 未知实体或配置级联在 映射例如 @ManyToOne(..,cascade="persist")。如果你不能 找出导致问题的实体实施 'AOBundle\Entity\Category#__toString()' 来获得线索。

但是当我使用 find 方法来获取它工作的类别实例时,但我不喜欢这个解决方案,我想让应用程序更快,有什么解决方案吗? 谢谢

【问题讨论】:

干净的方法是获取实体(例如使用->find(12) - 我不知道你为什么要花这么多时间来避免这种情况......你可以尝试 $category = $em->merge($category); 在你的$category->setId(12); 电话之后。 Lookup Doctrine 引用避免了实际加载实体的需要。 $category = $em->getReference(12); 【参考方案1】:

您可以为此使用 EntityManager 的 getReference 方法。

您的代码应如下所示。

$em = $this->get('doctrine')->getEntityManager();
$category = $em->getReference('AppBundle:Category', 12);

$product = new Product();
$product->setName('product 1');
$product->setCategory($category);

$em->persist($product);
$em->flush();

【讨论】:

这就是我需要在不进入数据库的情况下获取类别对象的方法。谢谢【参考方案2】:

我遇到了同样的问题,我的解决方案是避免将类别存储到变量中,但始终调用 find 函数。我还没有找到解释,但它帮助我继续前进。在您的示例中:

$em = $this->get('doctrine')->getManager();
$category = new Category();
$category->setId(12);
$em->persist($category);

$product = new Product();
$product->setName('product 1');
$product->setCategory($em->getRepository(Category::class)->find(12));
$em->persist($product);

$product = new Product();
$product->setName('product 2');
$product->setCategory($em->getRepository(Category::class)->find(12));
$em->persist($product);

$em->flush();

【讨论】:

【参考方案3】:

该错误意味着如果您持久化产品,则需要使用级联,因为您尚未创建类别。

所以你可以这样做:

$em = $this->get('doctrine')->getManager();
$category = new Category();
$category->setId(12);
$em->persist($category);

$product = new Product();
$product->setName('product 1');
$product->setCategory($category);
$em->persist($product);
$em->flush();

我不知道你为什么设置类别 ID,但我建议你删除它

【讨论】:

ID 为 12 的类别已经在数据库中,所以我为什么要创建另一个,这是违反主要约束【参考方案4】:

也许你没有选择现有的类别。

$em = $this->get('doctrine')->getManager(); 
$category = $em->getRepository('AppBundle:Category')->find(12);

$product = new Product();
$product->setName('product 1');
$product->setCategory($category);

$em->persist($product);
$em->flush();

【讨论】:

你可以在我的问题中看到我使用了 find 方法,我的问题是如何在不调用方法 find 的情况下创建类别 12 的新产品。只需创建一个 id 为 12 的类别并持久化产品

以上是关于学说 Symfony2 坚持与现有的关联实体的主要内容,如果未能解决你的问题,请参考以下文章

Symfony2 - 学说:模式:更新失败,实体在包之外(解耦)

学说 symfony2 错误:Cocina\ComprasBundle\Entity\Productos 类没有名为proveedores 的关联

使用 symfony2 缓存 ReadOnly 学说 2 实体的结果

Symfony 2 实体连接或学说查询连接

未定义索引:joinColumns 学说 + symfony2

基于模型实例获取学说结果