从Array到Doctrine / ArrayCollection:实体ID(日期)问题

时间:2014-11-12 13:53:15

标签: symfony doctrine-orm

我有这个场景

实体

class Foo
{
  /**
   * @ORM\Id
   * @ORM\Column(type="date")
   */
  protected $date;

  /**
   * @ORM\Id
   * @ORM\ManyToOne(targetEntity"Bar", inversedBy="foo")
   */
  protected $bar;

  [...]
}

存储库

class FooRepository extends EntityRepository
{
  public function dummyNameFunction()
  {
    $q = $this->createQueryBuilder('foo')
               ->//some dummy "components" added to builder
               ->getQuery()
    ;

    //I need an ArrayCollection as I want to take advantage of
    //Doctrine's ArrayCollection filter() function
    return new ArrayCollection($q->getResult()); 
  }
}

问题

只要我尝试从db中获取数据,就会出现此错误

  

ContextErrorException:Catchable Fatal Error:类DateTime的对象   无法转换为字符串   /path/to/project/vendor/doctrine/orm/lib/Doctrine/ORM/UnitOfWork.php   第2504行

对我来说,这很“非常清楚”:从Array对象转换为ArrayCollection,Doctrine希望使用实体的id(s)索引全新的ArrayCollection,但是,由于密钥是日期时间,因此PHP本身不提供__toString()方法(或等效方法)。

我想到的可能的解决方案:

  • 添加一个整数字段作为id。从$date$bar中删除ID并设置约束以使其唯一。缺点:我有一个完全没用的文件。
  • Register一个学说自定义映射类型,基本上是一个带有__toString魔术方法的Date。缺点:我现在不会,因为我还没有尝试过。。第二个解决方案似乎有效,但没有使用__toString()魔术方法。这有点“破解”而且有点脏。您可以在下面找到解决方案(*)

问题

  1. 与我的两种可能的解决方案相比,有人知道更好或“更快”的方法吗?
  2. (附带问题)这是一个“真正的”问题吗? Doctrine2 devel有可能没有将日期视为键吗?
  3. 脏溶液(*)

    首先,您需要定义Doctrine2服装类型。你怎么能这样做?
    我在我的包中创建了一个文件夹(以保持Doctrine2原始包结构安全)Doctrine\DBAL\Types。然后,在里面,我创建了这个类

    <?php
    
    namespace Company\BundleName\Doctrine\DBAL\Types;
    
    use Doctrine\DBAL\Types\DateType;
    use Doctrine\DBAL\Platforms\AbstractPlatform;
    
    class CustomDate extends DateType
    {
        private $date_value;
    
        public function getName()
        {
            return 'custom_date';
        }
    
        public function convertToPHPValue($value, AbstractPlatform $platform)
        {
            $date = parent::convertToPHPValue($value, $platform);
            $this->date_value = $date;
    
            return $date->format('Y-m-d');
        }
    
        public function convertToDatabaseValue($value, AbstractPlatform $platform)
        {
            return ($value !== null)
                ? $value : null;
        }
    }
    

    然后我添加了一个boot()方法来捆绑bootstrap文件(你需要在AppKernel.php中注册bundle所需的文件)

    public function boot()
    {
        $em = $this->container->get('doctrine.orm.entity_manager');
        Type::addType('custom_date', 'Company\BundleName\Doctrine\DBAL\Types\CustomDate');
        $em->getConnection()->getDatabasePlatform()->registerDoctrineTypeMapping('custom_date','custom_date');
    }
    

    之后我就是mod。 Foo的$date变量

    的映射
      /**
       * @ORM\Id
       * @ORM\Column(type="custom_date")
       */
      protected $date;
    

    注意:如果您使用任何类型提示,请记住正确更改getter和setter

1 个答案:

答案 0 :(得分:0)

似乎唯一的解决方案是创建一个全新的学说类型(我称之为#34;脏解决方案&#34;此处)因为UnitOfWork需要字符串或整数才能正常工作。

来源:Doctrine 2 ORM DateTime field in identifier