J'essaye d'écrire des tests en utilisant DB en mémoire. J'ai écrit un sql pour nettoyer et stocker des données dans DB. Mais j'ai une exception:
spring.h2.console.enabled=true spring.datasource.url=jdbc:h2:mem:db;DB_CLOSE_DELAY=-1 spring.datasource.driverClassName=org.h2.Driver spring.datasource.username=sa spring.datasource.password= spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
Mon sql:
insert into users (user_id, name, created_on, modified_on) values ('e7485042-b46b-11e9-986a-b74e614de0b0', 'Ann', null, null); insert into product(product_id, name, created_on, modified_on) VALUES ('f3a775de-b46b-11e9-95e4-af440b6044e6', 'product1', '2019-08-01 17:51:51.000000', '2019-08-01 17:51:51.000000'); insert into products_users(user_id, product_id) VALUES ('e7485042-b46b-11e9-986a-b74e614de0b0', 'f3a775de-b46b-11e9-95e4-af440b6044e6');
Mon application.properties:
Caused by: org.h2.jdbc.JdbcSQLDataException: Hexadecimal string contains non-hex character: "e7485042-b46b-11e9-986a-b74e614de0b0"; SQL statement: insert into users (user_id, name, created_on, modified_on) values ('e7485042-b46b-11e9-986a-b74e614de0b0', 'Ann', null, null) -- ('e7485042-b46b-11e9-986a-b74e614de0b0', 'Ann', NULL, NULL) [90004-199]
3 Réponses :
J'ai résolu ce problème en ajoutant spring.jpa.hibernate.ddl-auto = none
à mon fichier application.properties
Comment est-ce possible? ddl-auto = none empêchera la création de tables dans votre base de données h2 et donc aucune entrée ne pourra être insérée .... De plus: si vous travaillez avec spring boot et avez h2 sur votre classpath (scope test), h2 est automatiquement configuré pour vous rendant votre configuration redondante (sauf pour la console enabled = true)
cela n'a aucun rapport avec le sujet de la question
La cause réelle de ce problème est le mappage entre votre objet et l'instruction create table
générée par hibernate ( ddl-auto: create
) utilisée pour créer votre base de données h2 schéma.
Si vous activez la sortie de ces instructions ddl
en utilisant:
Hibernate: create table <your_table> ( id bigint generated by default as identity, ..., <your_object> binary(255), ... primary key (id) )
, vous verrez probablement que votre UUID code> class a été mappé à une colonne binaire de votre base de données.
spring.jpa.properties.hibernate.show_sql=true spring.jpa.properties.hibernate.use_sql_comments=true spring.jpa.properties.hibernate.format_sql=true logging.level.org.hibernate.type=TRACE
Cela signifie que votre chaîne uuid contient des caractères non autorisés. Vous avez besoin d'une colonne varchar (
. Il existe plusieurs stratégies de solution, l'une d'elles consiste à définir un type, voir cette réponse StackOverflow a>. Vous pouvez lire sur les colonnes binaire
sur le Site de référence MySQL .
L'utilisation de spring.datasource.url = jdbc: h2: mem: testdb; MODE = MYSQL a résolu le problème pour moi.
Ou l'ajout d'une annotation @Type dans le champ UUID devrait résoudre le problème :
@Id @Type(type="uuid-char") private UUID user_id;
Pouvez-vous expliquer ce que cela fait?
Ma réponse explique en fait ce qui cause cela et ne fournit pas de réponse par copier-coller. ;-)
Essayez de supprimer les traits d'union des valeurs de chaîne UUID.
Quel est le type de données de
user_id
?@MarkRotteveel, uuid
@GordThompson, alors j'obtiens MethodArgumentTypeMismatchException: Échec de conversion de la valeur de type «java.lang.String» en type requis «java.util.UUID»; l'exception imbriquée est java.lang.IllegalArgumentException: Chaîne UUID non valide: e7485042b46b11e9986ab74e614de0b0
La suppression des tirets signifie que vous vous retrouverez avec une chaîne qui ne respecte pas les conventions de format UUID. La reconversion d'un format binaire en un UUID valide entraîne donc une incompatibilité de type.
@kateswerg l'avez-vous finalement réglé?
@EnricoGiurin Je l'ai réglé. Veuillez lire attentivement ma réponse pour comprendre ce qui la cause exactement et comment la résoudre.