Este foro ya no está activo, así que no puedes publicar nuevas preguntas ni responder a las preguntas existentes.

Cómo adaptar con Gedmo/Doctrine el formato de las columnas timestamp para Oracle

2 de julio de 2014

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

#1

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

2 julio 2014, 9:03
#2

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

8 julio 2014, 4:02
#3

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

8 julio 2014, 7:05
#4

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

8 julio 2014, 8:37