Symfony2:Doctrine 不会在 OneToMany 关系上从 DB 返回 Collection



我的系统中有一个关系有问题。我很确定我这样做是正确的,并且我在代码中有一个我看不到的错误。

我在下面粘贴了我的课程。基本上,当我做fighter.getFighterAttributes()时,我得到一个空数组。它不会发生在类中的其他关系中。此外,当我查看日志时,我看到正在调用其他关系,但没有调用 FighterAttributes()。

该表包含已使用实体插入的条目。

它必须是我的代码中的一个错误,不确定是否:(

在类和日志下方。

<?php
namespace AcmeAppBundleEntity;
use DoctrineORMMapping as ORM;
use SymfonyComponentValidatorConstraints as Assert;
/**
 * @ORMEntity(repositoryClass="AcmeAppBundleRepositoryFighterRepository")
 */
class Fighter
{
    /**
     * @ORMColumn(type="integer")
     * @ORMId
     * @ORMGeneratedValue(strategy="AUTO")
     */
    protected $id;
    /**
     * @ORMColumn(type="string", length=100)
     */
    protected $firstName;

    /**
     * @ORMOneToMany(targetEntity="Contract", mappedBy="fighter")
     */
    protected $contracts;
    /**
     * @ORMManyToMany(targetEntity="Bout", mappedBy="fighters")
     */
    protected $bouts;
    /**
     * @ORMOneToMany(targetEntity="FighterAttribute", mappedBy="fighter")
     */
    protected $fighterAttributes;
// Custom ------------------------------------------------
    /**
     * Set createDT
     */
    public function setCreateDT()
    {
        $this->createDT = new DateTime("now");
    }
// Automated ---------------------------------------------
    /**
     * Get id
     *
     * @return integer 
     */
    public function getId()
    {
        return $this->id;
    }
    /**
     * Set firstName
     *
     * @param string $firstName
     * @return Fighter
     */
    public function setFirstName($firstName)
    {
        $this->firstName = $firstName;
        return $this;
    }
    /**
     * Get firstName
     *
     * @return string 
     */
    public function getFirstName()
    {
        return $this->firstName;
    }

    /**
     * Add bouts
     *
     * @param AcmeAppBundleEntityBout $bouts
     * @return Fighter
     */
    public function addBout(AcmeAppBundleEntityBout $bouts)
    {
        $this->bouts[] = $bouts;
        return $this;
    }
    /**
     * Remove bouts
     *
     * @param AcmeAppBundleEntityBout $bouts
     */
    public function removeBout(AcmeAppBundleEntityBout $bouts)
    {
        $this->bouts->removeElement($bouts);
    }
    /**
     * Get bouts
     *
     * @return DoctrineCommonCollectionsCollection 
     */
    public function getBouts()
    {
        return $this->bouts;
    }
    /**
     * Add contracts
     *
     * @param AcmeAppBundleEntityContract $contracts
     * @return Fighter
     */
    public function addContract(AcmeAppBundleEntityContract $contracts)
    {
        $this->contracts[] = $contracts;
        return $this;
    }
    /**
     * Remove contracts
     *
     * @param AcmeAppBundleEntityContract $contracts
     */
    public function removeContract(AcmeAppBundleEntityContract $contracts)
    {
        $this->contracts->removeElement($contracts);
    }
    /**
     * Get contracts
     *
     * @return DoctrineCommonCollectionsCollection 
     */
    public function getContracts()
    {
        return $this->contracts;
    }

    /**
     * Constructor
     */
    public function __construct()
    {
        $this->contracts = new DoctrineCommonCollectionsArrayCollection();
        $this->bouts = new DoctrineCommonCollectionsArrayCollection();
        $this->fighterAttributes = new DoctrineCommonCollectionsArrayCollection();
        $this->setCreateDT();
    }

    /**
     * Add fighterAttributes
     *
     * @param AcmeAppBundleEntityFighterAttribute $fighterAttributes
     * @return Fighter
     */
    public function addFighterAttribute(AcmeAppBundleEntityFighterAttribute $fighterAttributes)
    {
        $this->fighterAttributes[] = $fighterAttributes;
        return $this;
    }
    /**
     * Remove fighterAttributes
     *
     * @param AcmeAppBundleEntityFighterAttribute $fighterAttributes
     */
    public function removeFighterAttribute(AcmeAppBundleEntityFighterAttribute $fighterAttributes)
    {
        $this->fighterAttributes->removeElement($fighterAttributes);
    }
    /**
     * Get fighterAttributes
     *
     * @return DoctrineCommonCollectionsCollection 
     */
    public function getFighterAttributes()
    {
        return $this->fighterAttributes;
    }
}

日志如下:

[2014-02-14 01:36:13] doctrine.DEBUG: SELECT ... FROM Fighter t0 WHERE t0.id = ? LIMIT 1 ["110"] []
[2014-02-14 01:36:13] doctrine.DEBUG: SELECT ... FROM Contract t0 WHERE t0.fighter_id = ? [110] []
[2014-02-14 01:36:13] doctrine.DEBUG: SELECT ... FROM Bout t0 INNER JOIN BoutFighter ON t0.id = BoutFighter.bout_id WHERE BoutFighter.fighter_id = ? [110] []

请注意,没有 FighterAttribute 的条目。

职业战士属性如下:

<?php
namespace AcmeAppBundleEntity;
use DoctrineORMMapping as ORM;
/**
 * @ORMEntity
 */
class FighterAttribute
{
    /**
     * @ORMColumn(type="integer")
     * @ORMId
     * @ORMGeneratedValue(strategy="AUTO")
     */
    protected $id;
    /**
     * @ORMColumn(type="integer")
     */
    protected $amount;
    /**
     * @ORMManyToOne(targetEntity="Fighter", inversedBy="fighterAttributes")
     */
    protected $fighter;
    /**
     * @ORMManyToOne(targetEntity="Attribute")
     */
    protected $attribute;

    /**
     * Get id
     *
     * @return integer 
     */
    public function getId()
    {
        return $this->id;
    }
    /**
     * Set fighter
     *
     * @param AcmeAppBundleEntityFighter $fighter
     * @return FighterAttribute
     */
    public function setFighter(AcmeAppBundleEntityFighter $fighter = null)
    {
        $this->fighter = $fighter;
        return $this;
    }
    /**
     * Get fighter
     *
     * @return AcmeAppBundleEntityFighter 
     */
    public function getFighter()
    {
        return $this->fighter;
    }
    /**
     * Set attribute
     *
     * @param AcmeAppBundleEntityAttribute $attribute
     * @return FighterAttribute
     */
    public function setAttribute(AcmeAppBundleEntityAttribute $attribute = null)
    {
        $this->attribute = $attribute;
        return $this;
    }
    /**
     * Get attribute
     *
     * @return AcmeAppBundleEntityAttribute 
     */
    public function getAttribute()
    {
        return $this->attribute;
    }
    /**
     * Set amount
     *
     * @param integer $amount
     * @return FighterAttribute
     */
    public function setAmount($amount)
    {
        $this->amount = $amount;
        return $this;
    }
    /**
     * Get amount
     *
     * @return integer 
     */
    public function getAmount()
    {
        return $this->amount;
    }
}

更新

此代码打印"null"

$em = $this->getDoctrine()->getManager();
        $fighter = $em->getRepository('AcmeAppBundle:Fighter')
            ->findOneById($fighter_id);
        DoctrineCommonUtilDebug::dump($fighter->getFighterAttributes(), 1);
        die();

此代码打印战斗机属性:

$em = $this->getDoctrine()->getManager();
        $fighter = $em->getRepository('AcmeAppBundle:Fighter')
            ->findOneById($fighter_id);
        $attributes = $em->getRepository('AcmeAppBundle:FighterAttribute')
            ->findByFighter($fighter);
        DoctrineCommonUtilDebug::dump($attributes, 1);
        die();

输出:

array (size=12) 0 => string 'AcmeAppBundleEntityFighterAttribute' (length=38) 1 => string 'AcmeAppBundleEntityFighterAttribute' (length=38) 2 => string 'AcmeAppBundleEntityFighterAttribute' (length=38) 3 => string 'AcmeAppBundleEntityFighterAttribute' (length=38) 4 => string 'AcmeAppBundleEntityFighterAttribute' (length=38) 5 => string 'AcmeAppBundleEntityFighterAttribute' (length=38) 6 => string 'AcmeAppBundleEntityFighterAttribute' (length=38) 7 => string 'AcmeAppBundleEntityFighterAttribute' (length=38) 8 => string 'AcmeAppBundleEntityFighterAttribute' (length=38) 9 => string 'AcmeAppBundleEntityFighterAttribute' (length=38) 10 => string 'AcmeAppBundleEntityFighterAttribute' (length=38) 11 => string 'AcmeAppBundleEntityFighterAttribute' (length=38) 

此代码:

$em = $this->getDoctrine()->getManager();
        $fighter = $em->getRepository('AcmeAppBundle:Fighter')
            ->findOneById($fighter_id);
        $attributes = $em->getRepository('AcmeAppBundle:FighterAttribute')
            ->findByFighter($fighter);
        foreach ($attributes as $attribute)
        {
            $fighter->addFighterAttribute($attribute);
        }
        $em->persist($fighter);
        $em->flush();
        $fighter1 = $em->getRepository('AcmeAppBundle:Fighter')
            ->findOneById($fighter_id);
        DoctrineCommonUtilDebug::dump($fighter1->getFighterAttributes(), 1);
        die();

输出:

array (size=12) 0 => string 'AcmeAppBundleEntityFighterAttribute' (length=38) 1 => string 'AcmeAppBundleEntityFighterAttribute' (length=38) 2 => string 'AcmeAppBundleEntityFighterAttribute' (length=38) 3 => string 'AcmeAppBundleEntityFighterAttribute' (length=38) 4 => string 'AcmeAppBundleEntityFighterAttribute' (length=38) 5 => string 'AcmeAppBundleEntityFighterAttribute' (length=38) 6 => string 'AcmeAppBundleEntityFighterAttribute' (length=38) 7 => string 'AcmeAppBundleEntityFighterAttribute' (length=38) 8 => string 'AcmeAppBundleEntityFighterAttribute' (length=38) 9 => string 'AcmeAppBundleEntityFighterAttribute' (length=38) 10 => string 'AcmeAppBundleEntityFighterAttribute' (length=38) 11 => string 'AcmeAppBundleEntityFighterAttribute' (length=38) 

感谢您的帮助!!

好的。所以我发现了这个问题。正是我一直在玩的缓存设置给我带来了各种各样的问题。

看到即使我更新了一些对象,应用程序的行为也不稳定并且无法识别某些更改。即使我已经多次清除了应用程序缓存,也需要清除的是APC缓存。

我现在决定禁用它,因为我仍在开发中,但我认为清除 APC 缓存也会解决这个问题。在 config_dev.yml 中,我评论了以下内容:

#doctrine:
#    orm:
#        metadata_cache_driver: apc
#        result_cache_driver: apc
#        query_cache_driver: apc

@Patt,感谢您的帮助,通过您的解决方案帮助我弄清楚了,但是在我执行此更改后,您建议的代码更改并没有增加价值。正如我怀疑的那样,没有必要更新关系的非拥有方,除非当时有计划使用它或进行某种类型的级联持久性,而我不是。

最新更新