2009-01-14 7 views
10

J'ai les classes d'entités JPA suivantes (exemple de cas). Une maison appartient à une seule rue. Une rue a beaucoup de maisons. J'ai le type de génération défini sur identity, qui est supposé affecter automatiquement un nouvel ID. Lorsque vous créez une nouvelle maison avec une nouvelle rue, je dois d'abord créer et persister Street, puis House. C'est parce que je n'ai pas défini CascadeType sur PERSIST, donc cela doit être fait manuellement [1]. Cependant, lors de l'insertion d'une rue nouvellement créée:Hibernate génère une requête SQL non valide avec MySQL

Street street = new Street(); 
entityManager.persist(street); 

Hibernate/JPA génère la requête SQL suivante:

insert into Street default values 

qui MySQL n'aime pas.

Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'default values' at line 1 

Des idées pourquoi? J'utilise Java 6, MySQL 5.0.67 avec l'implémentation de JPA de Hibernate (version 3.2.1.ga).

[1] EJB 3 dans les pages d'action 318-319

Répondre

11

SQL standard spécifie cette syntaxe en option pour INSERT:

INSERT INTO <Table Name> DEFAULT VALUES 

Ceci est la syntaxe SQL juridique, prise en charge, par exemple, par Microsoft SQL Server, PostgreSQL , et SQLite, mais pas par Oracle, IBM DB2 ou MySQL.

MySQL prend en charge la syntaxe du langage qui permettent d'atteindre le même résultat:

INSERT INTO <Table Name>() VALUES() 

INSERT INTO <Table Name> (col1, col2, col3) VALUES (DEFAULT, DEFAULT, DEFAULT) 

En veille prolongée, vous devez configure le dialecte SQL correctement, et il est à Hibernate de générer du SQL valide pour la cible marque SGBDR.

import org.hibernate.cfg.Configuration; 

Configuration cfg = new Configuration(); 
cfg.setProperty("hibernate.dialect", "org.hibernate.dialect.MySQLInnoDBDialect"); 

Vous pouvez également spécifier des propriétés en plaçant un fichier nommé hibernate.properties dans un répertoire racine du classpath.

11

Si vous n'avez pas d'erreur dans votre instruction SQL, vous pouvez vérifier le nom de la colonne de votre table car il peut contenir un nom prédéfini utilisé par Mysql; par exemple 'column' qui ne peut pas être utilisé comme nom de colonne de table

+0

Merci, vous avez sauvé mes heures de dur labeur. – Heisenberg

+0

J'utilisais 'key' et 'value' comme noms de colonnes. Woops. –

7

Une autre situation où vous pourriez avoir cette exception est quand vous avez des mots réservés en tant que colonnes pour la table. Par exemple, 'to' et 'from' ne sont pas des noms de colonnes appropriés pour MySQL. De toute évidence, il s'agit d'un bogue dans Hibernate, qui ne vérifie pas ces colonnes et continue de fonctionner sans erreur même si la table n'est pas créée.

+0

C'était vraiment un gros indice. –