Tengo un problema al intentar insertar valores en una base de datos H2 en memoria.
Tengo esta Entidad:
@Entity @Table(name="myTable") public class MyEntity { @Id @GeneratedValue(strategy = GenerationType.AUTO) private long id; @Column(name = "startDate") @DateTimeFormat(pattern="yyy-MM-dd-HH.mm.ss") private Date startDate; @Column(name = "endDate") @DateTimeFormat(pattern="yyy-MM-dd-HH.mm.ss") private Date endDate; }
He usado el patrón yyy-MM-dd-HH.mm.ss
porque las fechas tienen un formato como 2021-06-14-00.00.00
o 2021-12-31-23.59.59
.
El @DateTimeFormat
importado es org.springframework.format.annotation.DateTimeFormat;
y Date
es java.util.Date
.
Para insertar valores en la base de datos, tengo este script:
INSERT INTO myTable (ID, START_DATE, END_DATE) VALUES (1, '2020-08-07-00.00.00', '2021-12-31-23.59.59'), (2, '2020-04-03-14.00.00', '2021-01-14-18.30.00'), (3, '2020-09-15-00.00.00', '2021-06-15-11.00.00'), (4, '2020-01-18-16.00.00', '2021-12-31-23.59.59');
Pero arroja un error:
Caused by: org.h2.jdbc.JdbcSQLDataException: Imposible interpretar la constante "TIMESTAMP" "2021-12-31-23.59.59" Cannot parse "TIMESTAMP" constant "2021-12-31-23.59.59"; SQL statement: INSERT INTO myTable (ID, ... ... Caused by: java.lang.NumberFormatException: 31-23.59.59
El texto del error que no está en inglés es algo así como "No se puede interpretar la constante"TIMESTAMP"".
También he probado algunas cosas y (¡esto es importante!) eliminando horas, minutos y segundos, el programa funciona , así que supongo que es el patrón el que no es correcto.
Este script SQL funciona:
INSERT INTO myTable (ID, START_DATE, END_DATE) VALUES (1, '2020-08-07', '2021-12-31'), (2, '2020-04-03', '2021-01-14'), (3, '2020-09-15', '2021-06-15'), (4, '2020-01-18', '2021-12-31');
Revisé un probador de DateTimeFormat en línea y la fecha actual con mi patrón es 2021-12-21-17.44.32
, pero incluso crear la tabla usando solo esa fecha arrojó el error.
Más información sobre la mesa:
La tabla (y también las columnas) se crea usando spring.jpa.hibernate.ddl-auto=update
, así que asumo que el tipo de columna es DATE
(como campo de entidad).
Así que estoy tratando de insertar una Cadena con formato yyy-MM-dd-HH.mm.ss
en una columna de DATE
(si no me equivoco).
¿Entonces, cuál es el problema? ¿No es posible insertar este patrón como fecha de cadena en un H2 en la base de datos de memoria?
Gracias por adelantado.
Si solo está tratando de insertar java.util.Date
en una columna TIMESTAMP
, no necesita @DateTimeFormat
. No está analizando nada, parte del objeto Date
y JPA lo traduce al tipo de datos SQL adecuado.
Defina la columna de esta manera:
@Column(name = "startDate") @Temporal(value=TemporalType.DATE) private Date startDate;
Y deberías estar listo para irte.
Actualizar
Si solo funciona el patrón DATE
y no funciona ningún patrón TIMESTAMP
, significa que la columna se definió con el tipo de datos incorrecto. DATE y TIMESTAMP son dos tipos de datos H2 diferentes (y en todos los demás DDBB, pero pueden tener nombres diferentes)
Su problema no es la capa JPA definida en su código Java sino los scripts que ejecuta.
INSERT INTO myTable (ID, START_DATE, END_DATE) VALUES (1, '2020-08-07-00.00.00', '2021-12-31-23.59.59'), (2, '2020-04-03-14.00.00', '2021-01-14-18.30.00'), (3, '2020-09-15-00.00.00', '2021-06-15-11.00.00'), (4, '2020-01-18-16.00.00', '2021-12-31-23.59.59');
Esto no tiene nada que ver con cómo ha definido su capa JPA. Para ese script cuando se ejecuta el @DateTimeFormat(pattern="yyy-MM-dd-HH.mm.ss")
es completamente desconocido que haya definido en su código.
Esto es solo un script ejecutado en DB. ¿Cómo sabría la base de datos cómo convertir esta cadena en un objeto de fecha válido? Debe informar en su secuencia de comandos cómo debe ocurrir la conversión de Cadena a Fecha.
Lo siguiente debería funcionar ya que PARSEDATETIME
es la función para H2 por ese motivo.
INSERT INTO myTable (ID, START_DATE, END_DATE) VALUES (1, PARSEDATETIME('2020-08-07-00.00.00','yyyy-MM-dd-HH.mm.ss'), PARSEDATETIME('2021-12-31-23.59.59','yyyy-MM-dd-HH.mm.ss')
Compruebe también detenidamente lo que ejecuta yyy-MM-dd-HH.mm.ss
. yyy
no se ajusta a las edades que pones en los guiones ex 2020. Esto es yyyy
Suponiendo (h2, in-mem):
CREATE TABLE myTable(Id NUMBER primary key,START_DATE TIMESTAMP,END_DATE TIMESTAMP);
Luego:
INSERT INTO myTable (ID, START_DATE, END_DATE) VALUES
me gusta:
(1, {ts '2020-08-07 00:00:00'}, {ts '2021-12-31 23:59:59'}),
(con formato de hora estándar)
O:
(2, parsedatetime('2020-04-03-14.00.00', 'yyyy-MM-dd-HH.mm.ss'), parsedatetime('2021-01-14-18.30.00', 'yyyy-MM-dd-HH.mm.ss'));
(uno personalizado)
Referencias: