OneToMany关系没有填充儿童

时间:2014-05-11 17:03:40

标签: symfony doctrine one-to-many doctrine-query

我假设当一个实体与另一个实体具有OneToMany关系时,将在查询父实体时填充子实体。

$account = $this->Repository()->findById($organization, $id, $accountList);
print_r($account->getAttributes()); //I would expect the children to be populated/returned when making this call

我希望会为帐户返回AccountAttributes,但$account->getAttributes()会返回null。

任何想法?

帐户实体

<?php

namespace Application\AccountBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;

use Application\AccountBundle\Entity\AccountAttribute;

/**
 * Account
 *
 * @ORM\Table(name="accounts")
 * @ORM\Entity(repositoryClass="Application\AccountBundle\Repository\AccountRepository")
 */
class Account
{
    /**
     * @var integer
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @var string
     *
     * @ORM\Column(name="display_name", type="string", length=255)
     */
    private $displayName;

    /**
     * @var \Application\OrganizationBundle\Entity\Organization
     *
     * @ORM\ManyToOne(targetEntity="Application\OrganizationBundle\Entity\Organization")
     * @ORM\JoinColumns({
     *   @ORM\JoinColumn(name="organization_id", referencedColumnName="id")
     * })
     */
    private $organization;

    /**
     * @var boolean
     *
     * @ORM\Column(name="active", type="boolean")
     */
    private $active;

    /**
     * @var \DateTime
     *
     * @ORM\Column(name="deactivated", type="datetime")
     */
    private $deactivated;

    /**
     * @var boolean
     *
     * @ORM\Column(name="deleted", type="boolean")
     */
    private $deleted;

    /**
     * @var \DateTime
     *
     * @ORM\Column(name="updated", type="datetime")
     */
    private $updated;

    /**
     * @var \DateTime
     *
     * @ORM\Column(name="created", type="datetime")
     */
    private $created;

    /**
    *
    * @var ArrayCollection
    *
    * @ORM\OneToMany(targetEntity="AccountAttribute", mappedBy="account", cascade={"ALL"}, indexBy="attribute")
    * 
    */
    private $attributes;

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

    /**
     * Get id
     *
     * @return integer
     */
    public function getId()
    {
        return $this->id;
    }

    /**
     * Set displayName
     *
     * @param  string  $displayName
     * @return Account
     */
    public function setDisplayName($displayName)
    {
        $this->displayName = $displayName;

        return $this;
    }

    /**
     * Get displayName
     *
     * @return string
     */
    public function getDisplayName()
    {
        return $this->displayName;
    }

    /**
     * Set active
     *
     * @param  boolean $active
     * @return Account
     */
    public function setActive($active)
    {
        $this->active = $active;

        return $this;
    }

    /**
     * Get active
     *
     * @return boolean
     */
    public function getActive()
    {
        return $this->active;
    }

    /**
     * Set deactivated
     *
     * @param  \DateTime $deactivated
     * @return Account
     */
    public function setDeactivated($deactivated)
    {
        $this->deactivated = $deactivated;

        return $this;
    }

    /**
     * Get deactivated
     *
     * @return \DateTime
     */
    public function getDeactivated()
    {
        return $this->deactivated;
    }

    /**
     * Set deleted
     *
     * @param  boolean $deleted
     * @return Account
     */
    public function setDeleted($deleted)
    {
        $this->deleted = $deleted;

        return $this;
    }

    /**
     * Get deleted
     *
     * @return boolean
     */
    public function getDeleted()
    {
        return $this->deleted;
    }

    /**
     * Set updated
     *
     * @param  \DateTime $updated
     * @return Account
     */
    public function setUpdated($updated)
    {
        $this->updated = $updated;

        return $this;
    }

    /**
     * Get updated
     *
     * @return \DateTime
     */
    public function getUpdated()
    {
        return $this->updated;
    }

    /**
     * Set created
     *
     * @param  \DateTime $created
     * @return Account
     */
    public function setCreated($created)
    {
        $this->created = $created;

        return $this;
    }

    /**
     * Get created
     *
     * @return \DateTime
     */
    public function getCreated()
    {
        return $this->created;
    }

    public function getOrganization()
    {
        return $this->organization;
    }

    public function getAttributes()
    {
        return $this->attributes;
    }

    public function setAttributes($attributes)
    {
        foreach($attributes as $item)
        {
            $this->addAttribute($item);
        }
        return $this;
    }

    public function addAttribute(AccountAttribute $attribute)
    {
        $this->attributes->add($attribute);
        return $this;
    }

    public function getAttributeCollection()
    {
        $data = array();
        $attributes = $this->getAttributes();

        foreach ($attributes as $item)
        {
            $data[$item->getDataKey()] = $item->getDataValue();
        }

        return $data;
    }

}

帐户属性实体

<?php

namespace Application\AccountBundle\Entity;

use Doctrine\ORM\Mapping as ORM;

use Application\AccountBundle\Entity\Account;
use Application\AccountBundle\Entity\AccountAttribute;
use Application\OrganizationBundle\Entity\Organization;

/**
 * Account
 *
 * @ORM\Table(name="accountattribute")
 * @ORM\Entity(repositoryClass="Application\AccountBundle\Repository\AccountAttributeRepository")
 */
class AccountAttribute
{

    /**
     * @var \Application\AccountBundle\Entity\Account
     * @ORM\Id
     * @ORM\ManyToOne(targetEntity="Account", inversedBy="attributes")
     * @ORM\JoinColumn(name="account_id", referencedColumnName="id")
     */
    private $account;

    /**
     * @var \Application\OrganizationBundle\Entity\Organization
     * @ORM\Id
     * @ORM\ManyToOne(targetEntity="Application\OrganizationBundle\Entity\Organization")
     * @ORM\JoinColumns({
     *   @ORM\JoinColumn(name="organization_id", referencedColumnName="id")
     * })
     */
    private $organization;

    /**
     * @var string
     * @ORM\Id
     * @ORM\Column(type="string")
     */
    private $dataKey;

    /**
     * @var text
     * @ORM\Column(type="text")
     */
    private $dataValue;

    /**
     * @var \DateTime
     * @ORM\Column(name="updated", type="datetime")
     */
    private $updated;

    /**
     * @var \DateTime
     *
     * @ORM\Column(name="created", type="datetime")
     */
    private $created;

    public function __construct(Account $account, $organizationId, $key, $value )
    {
        $this->account = $account;
        $this->organizationId = $organizationId;
        $this->dataKey = $key;
        $this->dataValue = $key;
    }

    public function getKey()
    {
        return $this->dataKey;
    }

    public function setKey($key)
    {
        $this->dataKey = $key;
        return $this;
    }

    public function getValue()
    {
        return $this->dataValue;
    }

    public function setValue($value)
    {
        $this->dataValue = $value;
        return $this;
    }

    public function getAccount()
    {
        return $this->account;
    }

    public function setAccount(Account $account)
    {
        $this->account = $account;
        return $this;
    }
}

帐户存储库

<?php

namespace Application\AccountBundle\Repository;

use Doctrine\ORM\EntityRepository;
use Doctrine\ORM\NoResultException;
use Doctrine\ORM\Query;

use Application\AccountBundle\Entity\Account;

/**
 * AccountRepository
 *
 * This class was generated by the Doctrine ORM. Add your own custom
 * repository methods below.
 */
class AccountRepository extends EntityRepository
{
    public function findById($organization_id, $id, $accountList)
    {
        if( empty( $accountList ) )

            return null;

            $em = $this->getEntityManager();

            $emConfig = $em->getConfiguration();
            $emConfig->addCustomDatetimeFunction('YEAR', 'DoctrineExtensions\Query\Mysql\Year');
            $emConfig->addCustomDatetimeFunction('MONTH', 'DoctrineExtensions\Query\Mysql\Month');
            $emConfig->addCustomDatetimeFunction('DAY', 'DoctrineExtensions\Query\Mysql\Day');

            $q = $em
                ->createQuery(
                    "SELECT a
                        FROM ApplicationAccountBundle:Account a
                        WHERE
                            a.id IN ( " . implode(',', $accountList ) . ") AND
                            a.deleted = false AND
                            a.organization = :organization_id AND
                            a.id = :id AND
                            (
                                a.active = 1 OR
                                (
                                    a.active = 0 AND
                                    MONTH(a.deactivated) >= :current_month AND
                                    YEAR(a.deactivated) >= :current_year
                                 )
                            )
                    "
                )
                ->setParameters(
                    array(
                        'id' => $id,
                        'organization_id' => $organization_id,
                        'current_month' => date( "n" ),
                        'current_year' => date( "Y" )
                    )
                );
        try {
            $account = $q->getOneOrNullResult();
        } catch (NoResultException $e) {

        }

        return $account;
    }

    public function findAllAccounts($organization_id, $accountList)
    {

        if( empty( $accountList ) )

            return null;

        $em = $this->getEntityManager();

        $emConfig = $em->getConfiguration();
        $emConfig->addCustomDatetimeFunction('YEAR', 'DoctrineExtensions\Query\Mysql\Year');
        $emConfig->addCustomDatetimeFunction('MONTH', 'DoctrineExtensions\Query\Mysql\Month');
        $emConfig->addCustomDatetimeFunction('DAY', 'DoctrineExtensions\Query\Mysql\Day');

        $q = $em
            ->createQuery(
                "SELECT e
                    FROM ApplicationAccountBundle:Account a
                    WHERE
                        a.id IN ( " . implode(',', $accountList ) . ") AND
                        a.deleted = false AND
                        a.organization = :organization_id AND
                        (
                            a.active = 1 OR
                            (
                                a.active = 0 AND
                                MONTH(a.deactivated) >= :current_month AND
                                YEAR(a.deactivated) >= :current_year
                             )
                        )
                "
            )
            ->setParameters(
                array(
                    'organization_id' => $organization_id,
                    'current_month' => date( "n" ),
                    'current_year' => date( "Y" )
                )
            );

        try {
            $accounts = $q->getResult();
        } catch (NoResultException $e) {

        }

        return $accounts;
    }

    public function findByACL($userIdentity, $mask, $className)
    {
        $sql = <<<SELECTCLAUSE
            SELECT oid.object_identifier
                FROM acl_entries ent
                JOIN acl_object_identities oid ON
                    oid.class_id = ent.class_id
                JOIN acl_security_identities s ON
                    s.id = ent.security_identity_id
                JOIN acl_classes cls ON
                    cls.id = ent.class_id
                WHERE
                    ent.object_identity_id IS NOT NULL AND
                    (ent.mask & %d) AND
                    s.identifier = %s AND
                    cls.class_type = %s
                GROUP BY
                    oid.object_identifier;
SELECTCLAUSE;
        $connection = $this->getEntityManager()->getConnection();
        $query = sprintf(
            $sql,
            $mask,
            $connection->quote("{$userIdentity->getClass()}-{$userIdentity->getUsername()}"),
            $connection->quote($className)
        );

        //Execute query to get all of the IDs
        $ids = $connection->executeQuery($query)->fetchAll(\PDO::FETCH_COLUMN);

        return $ids;
    }

    public function save(Account $account)
    {
        $em = $this->getEntityManager();
        $em->getConnection()->beginTransaction();
        $em->persist($account);

        try {
            $em->flush();
            $em->getConnection()->commit();
        } catch (\Exception $e) {
            $em->getConnection()->rollback();
            echo "Unable to save Account";
        }

        return $account;
    }
}

表结构

CREATE TABLE `accounts` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `organization_id` int(11) NOT NULL,
  `display_name` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
  `active` tinyint(1) NOT NULL DEFAULT '1',
  `deactivated` datetime DEFAULT NULL,
  `deleted` tinyint(1) NOT NULL DEFAULT '0',
  `updated` datetime NOT NULL ON UPDATE CURRENT_TIMESTAMP,
  `created` datetime NOT NULL,
  PRIMARY KEY (`id`),
  KEY `IDX_FA6F25A332C8A3DE` (`organization_id`),
  CONSTRAINT `FK_FA6F25A332C8A3DE` FOREIGN KEY (`organization_id`) REFERENCES `organizations` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

CREATE TABLE `accountattribute` (
  `account_id` int(11) NOT NULL,
  `organization_id` int(11) NOT NULL,
  `dataKey` varchar(255) COLLATE utf8_unicode_ci NOT NULL DEFAULT '',
  `dataValue` text COLLATE utf8_unicode_ci NOT NULL,
  `updated` datetime NOT NULL,
  `created` datetime NOT NULL,
  PRIMARY KEY (`account_id`,`organization_id`,`dataKey`),
  KEY `organization_id` (`organization_id`),
  CONSTRAINT `accountattribute_ibfk_2` FOREIGN KEY (`organization_id`) REFERENCES `organizations` (`id`),
  CONSTRAINT `accountattribute_ibfk_1` FOREIGN KEY (`account_id`) REFERENCES `accounts` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

1 个答案:

答案 0 :(得分:2)

这是您的问题:在您的存储库调用中,您只选择了一个,因此只会填充该帐户。