【问题标题】:Doctrine Symfony2 persist association entity with existing one学说 Symfony2 坚持与现有的关联实体
【发布时间】: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);

标签: symfony doctrine


【解决方案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 的类别并持久化产品
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-21
    相关资源
    最近更新 更多