Hola, estoy desarrollando una aplicacion con Symfony2 y base de datos Oracle. Cuando mapeo las entidades tengo columnas datetime
, pero al correr el comando doctrine:migrations:migrate
las columnas se crean como timestamp
. Al momento de hacer un insert me da el siguiente error:
An exception occurred while executing 'INSERT INTO SSFCOMPGENERICO (fecha_creado, fecha_modificado, id, codigo, nombre, creado_por, modificado_por, obs) VALUES (?, ?, ?, ?, ?, ?, ?, ?)' with params ["2014-07-01 23:45:53", "2014-07-01 23:45:53", 3, 2, "data", "data", "ask", "asd"]: ORA-01843: not a valid month 500 Internal Server Error - DBALException 1 linked Exception: OCI8Exception »
¿Puedo configurar el Gedmo para adaptar el formato a la columna timestamp de Oracle?
Gracias.
Respuestas
Si estás seguro de que no vas a cambiar de base de datos en este proyecto, la solución más sencilla sería una de estas dos (yo optaría por la segunda opción):
- Cambiar el tipo de dato de esas columnas de fecha en los archivos de migración generados antes de aplicarlos.
- Formatear las fechas antes de hacer la consulta para adaptarla a lo que necesita Oracle.
Ya se que esta solución no parece muy "científica", pero al utilizar ORM a veces nos obsesionamos con abstraer toda la aplicación aún cuando sabemos que nunca cambiaremos de sistema de base de datos.
@javiereguiluz
Muchas gracias por respuesta. Tomé el segundo camino y he tratado de formatear las fechas para hacer los persist de las entidades que poseen columnas date
. Lo he intentado con la función date()
de PHP, con datetime
, desde el constructor o con el método setFechaCreado()
y no lo consigo. Con la función date()
me devuelve el siguiente error:
FatalErrorException: Error: Call to a member function format() on a non-object in C:\wamp\www\tesisend\TesisFunpisunet\vendor\ doctrine\dbal\lib\Doctrine\DBAL\Types\DateType.php line 44
y con la datetime:
ora-01861 literal does not match format string in oracle
/** * @var \Date * * @ORM\Column(name="fe_creado", type="date", nullable=true) */ private $fechaCreado; public function __construct() { // $this->fechaCreado = date('Y-M-D'); // $this->fechaCreado = new \DateTime('2000-01-01'); // $this->fechaCreado = new \DateTime(); // $this->fechaCreado = date('d/m/y H:i:s'); } /** * Set fechaCreado * * @param \DateTime $fechaCreado * * @return Timestampable */ public function setFechaCreado($fechaCreado) { $this->fechaCreado = $fechaCreado; return $this; } /** * Get fechaCreado * * @return \DateTime */ public function getFechaCreado() { return $this->fechaCreado; }
Comparo el formato con la base de datos que me devuelve con la siguiente consulta:
SELECT sysdate FROM dual; SYSDATE 14-07-07
He creado las fechas con ese formato yy-mm-dd
pero igual sigue saliendo la excepción. No se si me estoy saltando algo.
Gracias Saludos!
@kmiloxvii
Para quien lo pueda necesitar, encontre la solución en este bug del DoctrineBundle. Para solucionarlo solo se importa el servicio ya sea creando el service.yml
el cual se importa en el config.yml
o directamente en el mismo config.yml
:
oracle.listener: class: Doctrine\DBAL\Event\Listeners\OracleSessionInit tags: - { name: doctrine.event_listener, event: postConnect }
Una vez configurado el servicio, se generan las fechas adecuadamente. Se pueden generar usando la extensión Gedmo o con new \DateTime()
Saludos!
@kmiloxvii
Muchas gracias por explicarnos cómo solucionar este error. Como me parecía un poco raro lo de utilizar esta clase OracleSessionInit
, he buscado en el código de Doctrine y al parecer, para que funcione bien Doctrine con Oracle es necesario que tu máquina tenga las siguientes variables de entorno:
NLS_TIME_FORMAT = "HH24:MI:SS" NLS_DATE_FORMAT = "YYYY-MM-DD HH24:MI:SS" NLS_TIMESTAMP_FORMAT = "YYYY-MM-DD HH24:MI:SS" NLS_TIMESTAMP_TZ_FORMAT = "YYYY-MM-DD HH24:MI:SS TZH:TZM"
Lo que hace esta clase es precisamente asegurarse de que existan esas variables o establecerlas ella misma.
@javiereguiluz