83 votes

les valeurs DATETIME de manutention 0000-00-00 00:00:00 dans JDBC

J'obtiens une exception (voir ci-dessous) si j'essaie de faire

resultset.getString("add_date");

pour une connexion JDBC à une base de données MySQL contenant une valeur de type DATETIME de 0000-00-00 00:00:00 (la valeur quasi-nulle pour le type DATETIME), même si je suis juste essayer d'obtenir la valeur sous forme de chaîne, non pas comme un objet.

J'ai eu autour de ce en faisant

SELECT CAST(add_date AS CHAR) as add_date

ce qui fonctionne, mais semble stupide... est-il une meilleure façon de le faire?

Mon point est que je veux juste le raw DATETIME chaîne, afin que je puisse l'analyser moi-même comme est.

remarque: c'est ici où la 0000: (à partir de http://dev.mysql.com/doc/refman/5.0/en/datetime.html)

Illégale DATETIME, DATE, TIMESTAMP ou les valeurs sont converties en "zéro" valeur du type approprié ('0000-00-00 00:00:00', ou '0000-00-00').

L'exception spécifique est celui-ci:

SQLException: Cannot convert value '0000-00-00 00:00:00' from column 5 to TIMESTAMP.
SQLState: S1009
VendorError: 0
java.sql.SQLException: Cannot convert value '0000-00-00 00:00:00' from column 5 to TIMESTAMP.
    at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1055)
    at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:956)
    at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:926)
    at com.mysql.jdbc.ResultSetImpl.getTimestampFromString(ResultSetImpl.java:6343)
    at com.mysql.jdbc.ResultSetImpl.getStringInternal(ResultSetImpl.java:5670)
    at com.mysql.jdbc.ResultSetImpl.getString(ResultSetImpl.java:5491)
    at com.mysql.jdbc.ResultSetImpl.getString(ResultSetImpl.java:5531)

121voto

Brian Clozel Points 6473

Alternative la réponse, vous pouvez utiliser cette URL JDBC directement dans votre source de données de configuration:

jdbc:mysql://yourserver:3306/yourdatabase?zeroDateTimeBehavior=convertToNull

Edit:

Source: Manuel MySQL

Datetimes avec de zéro pour tous les composants (0000-00-00 ...) - Ces valeurs ne peuvent pas être représentés de manière fiable en Java. Connector/J 3.0.x toujours converti à la valeur NULL lorsque la lecture à partir d'un jeu de résultats.

Connector/J 3.1 déclenche une exception par défaut lorsque ces valeurs sont rencontrés, qui est la plus correcte comportement en fonction de l'JDBC et SQL normes. Ce comportement peut être modifié à l'aide de la zeroDateTimeBehavior propriété de configuration. Les valeurs permises sont:

  • exception (par défaut), ce qui déclenche une SQLException avec un SQLState de S1009.
  • convertToNull, qui renvoie la valeur NULL à la place de la date.
  • ronde, qui arrondit la date la plus proche à la valeur la plus proche est 0001-01-01.

Mise à jour: Alexander signalé un bug affectant mysql-connector-5.1.15 sur cette fonctionnalité. Voir le CHANGELOG sur le site officiel.

81voto

sarumont Points 1106

Je suis tombé sur cette tentative de résoudre le même problème. L'installation, je suis en train de travailler avec utilise JBOSS et mise en veille prolongée, j'ai donc dû le faire d'une manière différente. Pour le cas de base, vous devriez être en mesure d'ajouter zeroDateTimeBehavior=convertToNull de votre URI de connexion que par cette page de propriétés de configuration.

J'ai trouvé d'autres suggestions à travers le pays en se référant à mettre ce paramètre dans votre hibernate config:

Dans hibernate.cfg.xml:

<property name="hibernate.connection.zeroDateTimeBehavior">convertToNull</property>

Dans hibernate.propriétés:

hibernate.connection.zeroDateTimeBehavior=convertToNull

Mais j'ai dû le mettre dans mon mysql-ds.xml fichier pour JBOSS as:

<connection-property name="zeroDateTimeBehavior">convertToNull</connection-property>

Espérons que cela aide quelqu'un. :)

11voto

Arjan Points 7154

Mon point est que je veux juste le raw DATETIME chaîne, afin que je puisse l'analyser moi-même.

Cela me fait penser que votre "solution" n'est pas une solution de contournement, mais en fait, la seule façon d'obtenir la valeur de la base de données dans votre code:

SELECT CAST(add_date AS CHAR) as add_date

Par ailleurs, certaines plus de notes à partir de la documentation de MySQL:

MySQL Contraintes sur des Données non valides:

Avant MySQL 5.0.2, MySQL est pardonner illégale ou inappropriée de valeurs de données et contraint à valeurs légales pour l'entrée de données. Dans MySQL 5.0.2 et jusqu', qui reste le comportement par défaut, mais vous pouvez modifier le serveur SQL mode pour sélectionner les plus traditionnelles de traitement de mauvaises valeurs telles que le serveur rejette et abandonne l'état dans lequel ils se produisent.

[..]

Si vous essayez de stocker une valeur NULL dans une colonne qui ne prend pas les valeurs NULL, une erreur se produit pour la ligne unique de l'INSERT. Pour l'INSERTION de plusieurs lignes de déclarations ou pour l'INSERTION DANS ... les instructions SELECT, MySQL Server stocke la valeur implicite par défaut pour le type de données de colonne.

MySQL 5.x Types Date et Heure:

MySQL vous permet également de stocker '0000-00-00', comme un "dummy date" (si vous n'êtes pas à l'aide de la NO_ZERO_DATE mode SQL). C'est dans certains cas plus pratique (et utilise moins de données et d'index de l'espace) que l'utilisation de valeurs NULL.

[..]

Par défaut, lorsque MySQL rencontre une valeur pour une date ou type de temps qui est hors de portée ou autrement illégal pour le type (comme décrit au début de cette section), il convertit la valeur à la valeur "zéro" pour ce type.

5voto

Vadim Points 41

Si, après l’ajout de lignes :

continue d’être une erreur :

Recherchez les lignes :

remplacer les lignes suivantes, respectivement :

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X