symfony/doctrine: cannot use object without refreshing

独自空忆成欢 提交于 2019-12-24 08:48:01

问题


It's the first time I run into this problem. I want to create a doctrine object and pass it along without having to flush it.

Right after it's creation, I can display some value in the object, but I can't access nested object:

    $em->persist($filter);
    print_r($filter->getDescription() . "\n");
    print_r(count($filter->getAssetClasses()));
    die;

I get:

filter description -- 0

(I should have 19 assetClass)

If I flush $filter, i still have the same issue (why oh why !) The solution is to refresh it:

    $em->persist($filter);
    $em->flush();
    $em->refresh($filter);
    print_r($filter->getDescription() . " -- ");
    print_r(count($filter->getAssetClasses()));
    die;

I get:

filter description -- 19

unfortunately, you can't refresh without flushing.

On my entities, I've got the following:

in class Filter:

public function __construct()
{
    $this->filterAssetClasses = new ArrayCollection();
    $this->assetClasses = new ArrayCollection();
}

/**
 * @var Collection
 *
 * @ORM\OneToMany(targetEntity="FilterAssetClass",                         mappedBy="filterAssetClasses", cascade={"persist"})
 */
private $filterAssetClasses;

public function addFilterAssetClass(\App\CoreBundle\Entity\FilterAssetClass $filterAssetClass)
{
    $this->filterAssetClasses[] = $filterAssetClass;
    $filterAssetClass->setFilter($this);

    return $this;
}

in class FilterAssetClass:

/**
 * @var Filter
 *
 * @ORM\ManyToOne(targetEntity="App\CoreBundle\Entity\Filter", inversedBy="filterAssetClasses")
 */
private $filter;

/**
 * @var Filter
 *
 * @ORM\ManyToOne(targetEntity="AssetClass")
 */
private $assetClass;

public function setFilter(\App\CoreBundle\Entity\Filter $filter)
{
    $this->filter = $filter;

    return $this;
}

Someone else did write the code for the entities, and i'm a bit lost. I'm not a Doctrine expert, so if someone could point me in the good direction, that would be awesome.

Julien


回答1:


but I can't access nested object

Did you set those assetClasses in the first place?

When you work with objects in memory (before persist), you can add and set all nested objects, and use those while still in memory.

My guess is that you believe that you need to store objects to database in order for them to get their IDs assigned.

IMHO, that is a bad practice and often causes problems. You can use ramsey/uuid library instead, and set IDs in Entity constructor:

public function __construct() {
    $this->id = Uuid::uuid4();
}

A database should be used only as a means for storing data. No business logic should be there.

I would recommend this video on Doctrine good practices, and about the above mentioned stuff.




回答2:


Your problem is not related to doctrine nor the persist/flush/refresh sequence; the problem you describe is only a symptom of bad code. As others have suggested, you should not be relying on the database to get at your data model. You should be able to get what you are after entirely without using the database; the database only stores the data when you are done with it.

Your Filter class should include some code that manages this:

// Filter
public function __contsruct()
{
    $this->filterAssetClasses = new ArrayCollection();
}

/**
 * @ORM\OneToMany(targetEntity="FilterAssetClass", mappedBy="filterAssetClasses", cascade={"persist"})
 */
private $filterAssetClasses;


public function addFilterAssetClass(FilterAssetClass $class) 
{
    // assuming you don't want duplicates...
    if ($this->filterAssetClasses->contains($class) {
        return;
    }

    $this->filterAssetClasses[] = $class;

    // you also need to set the owning side of this relationship 
    //    for later persistence in the db
    // Of course you'll need to create the referenced function in your 
    //    FilterAssetClass entity

    $class->addFilter($this);
}

You may have all of this already, but you didn't show enough of your code to know. Note that you should probably not have a function setFilterAssetClass() in your Filter entity.



来源:https://stackoverflow.com/questions/43210485/symfony-doctrine-cannot-use-object-without-refreshing

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!