yml tutorial many inversejoincolumns column doctrine-orm

doctrine orm - tutorial - Campo Doctrine 2 ORM DateTime en el identificador



orm column (2)

En nuestras tablas de refID datos, las columnas refID y date son una clave primaria compuesta, con un campo del identificador asignado como datetime y datetime :

class corpWalletJournal { /** * @ORM/Column(name="refID", type="bigint", nullable=false) * @ORM/Id * @ORM/GeneratedValue(strategy="NONE") */ private $refID; /** * @ORM/Column(name="date", type="datetime", nullable=false) * @ORM/Id * @ORM/GeneratedValue(strategy="NONE") */ private $date; public function setRefID($refID) { $this->refID = $refID; } public function setDate(/DateTime $date) { $this->date = $date; } }

Si los describimos en la entidad como @ORM / Id, este código devolverá la excepción "no se puede convertir datetime en cadena" ...

$filter = array( ''date'' => $this->stringToDate($loopData[''date'']), ''refID'' => $loopData[''refID''] )); $oCorpWJ = $this->em->getRepository(''EveDataBundle:corpWalletJournal'')->findOneBy($filter); // ... $oCorpWJ->setDate($this->stringToDate($loopData[''date''])); // ...

Si describimos corpWalletJournal#date como una columna simple, el código funciona bien. ¿Por qué?

¿Cómo podemos lidiar con eso? Necesitamos tener la date y el refID en la clave primaria.

ADICIONAL:

Así que creé nueva clase.

use /DateTime; class DateTimeEx extends DateTime { public function __toString() { return $this->format(''Y-m-d h:i:s''); } }

Y nuevo tipo para ello.

use Doctrine/DBAL/Types/Type; use Doctrine/DBAL/Platforms/AbstractPlatform; use Eve/DataBundle/Entity/Type/DateTimeEx; class DateTimeEx extends Type { const DateTimeEx = ''datetime_ex''; public function getSQLDeclaration(array $fieldDeclaration, AbstractPlatform $platform) { return ''my_datetime_ex''; } public function convertToPHPValue($value, AbstractPlatform $platform) { return new DateTimeEx($value); } public function convertToDatabaseValue($value, AbstractPlatform $platform) { return $value->format(''Y-m-d h:i:s''); } public function getName() { return self::DateTimeEx; } public function canRequireSQLConversion() { return true; } }

¿Cómo puedo usarlos en entidad?

Mi clase de tipo (editada)

use Doctrine/DBAL/Types/Type; use Doctrine/DBAL/Platforms/AbstractPlatform; class DateTimeEx extends Type { const DateTimeEx = ''datetime_ex''; public function getSQLDeclaration(array $fieldDeclaration, AbstractPlatform $platform) { return ''my_datetime_ex''; } public function convertToPHPValue($value, AbstractPlatform $platform) { return $value; } public function convertToDatabaseValue($value, AbstractPlatform $platform) { return $value; } public function getName() { return self::DateTimeEx; } }


Doctrine 2 ORM necesita convertir los campos de identificador en cadenas en UnitOfWork . Esto es necesario para que el EntityManager pueda realizar un seguimiento de los cambios en sus objetos.

Como los objetos de tipo DateTime no implementan el método __toString forma nativa, convertirlos en cadenas no es tan simple como convertirlos en cadenas.

Por lo tanto, los tipos de date , datetime y datetime predeterminados no son compatibles como parte del identificador .

Para lidiar con esto, debe definir su propio tipo de campo personalizado mydatetime asignado a su propia clase MyDateTime que implementa __toString . De esa manera, el ORM puede manejar identificadores también si contienen objetos.

Aquí hay un ejemplo de cómo puede verse esa clase:

class MyDateTime extends /DateTime { public function __toString() { return $this->format(''U''); } }

Y aquí hay un ejemplo de cómo se vería el tipo DBAL personalizado:

use Doctrine/DBAL/Types/DateTimeType; use Doctrine/DBAL/Platforms/AbstractPlatform; class MyDateTimeType extends DateTimeType { public function convertToPHPValue($value, AbstractPlatform $platform) { $dateTime = parent::convertToPHPValue($value, $platform); if ( ! $dateTime) { return $dateTime; } return new MyDateTime(''@'' . $dateTime->format(''U'')); } public function getName() { return ''mydatetime''; } }

Luego lo registra con su configuración de ORM durante el arranque (depende del marco que esté usando). En Symfony, está documentado en la documentación de la doctrina de Symfony .

Después de eso, puedes usarlo en tus entidades:

class corpWalletJournal { // ... /** * @ORM/Column(name="date", type="mydatetime", nullable=false) * @ORM/Id * @ORM/GeneratedValue(strategy="NONE") */ private $date;


Ten cuidado con

return new DateTimeEx(''@'' . $dateTime->format(''U''));

La zona horaria no será buena. Deberías hacer :

$val = new DateTimeEx(''@'' . $dateTime->format(''U'')); $val->setTimezone($dateTime->getTimezone()); return $val;