Hibernate генерирует недопустимый запрос SQL с MySQL

У меня есть следующие классы сущностей JPA (примерный случай). Дом принадлежит одной улице. На улице много домов.

@Entity
public class House {
    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    public Integer id;

    public String name    

    @ManyToOne
    public Street street;
}

@Entity
public class Street {
    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    public Integer id;

    @OneToMany(mappedBy = "street")
    public Set<House> houses;
}

У меня есть тип поколения, установленный на личность, который должен автоматически назначать новый идентификатор.

При создании нового дома с новой улицей я должен сначала создать и сохранить улицу, а затем - дом. Это потому, что у меня CascadeType не установлен на PERSIST, поэтому это нужно делать вручную [1]. Однако при вставке вновь созданной улицы:

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

Hibernate / JPA генерирует следующий SQL-запрос:

insert into Street default values

что MySQL не любит.

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 

Есть идеи, почему? Я использую Java 6, MySQL 5.0.67 с реализацией JPA в Hibernate (версия 3.2.1.ga).

[1] EJB 3 в действии, страницы 318–319

Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
11
0
19 290
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

Ответ принят как подходящий

Стандартный SQL определяет этот необязательный синтаксис для INSERT:

INSERT INTO <Table Name> DEFAULT VALUES

Это допустимый синтаксис SQL, поддерживаемый, например, Microsoft SQL Server, PostgreSQL и SQLite, но не Oracle, IBM DB2 или MySQL.

MySQL поддерживает другой синтаксис, который дает тот же результат:

INSERT INTO <Table Name> () VALUES ()

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

В Hibernate вы должны правильно настроить диалекта SQL, и именно Hibernate должен сгенерировать действительный SQL для целевой марки СУБД.

import org.hibernate.cfg.Configuration;

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

Вы также можете указать свойства, поместив файл с именем hibernate.properties в корневой каталог пути к классам.

Если в вашем операторе SQL нет ошибки, вы можете проверить имя столбца таблицы, поскольку оно может содержать предопределенное имя, которое использует Mysql; например, "столбец", который нельзя использовать в качестве имени столбца таблицы

Я использовал «ключ» и «значение» в качестве имен столбцов. Вупс.

Ian Newland 07.05.2016 15:47

Другая ситуация, когда у вас может быть это исключение, - это когда вы зарезервировали слова в качестве столбцов для таблицы. Например, «to» и «from» не подходят для имен столбцов MySQL. Очевидно, что это ошибка Hibernate, что он не проверяет такие столбцы и, более того, продолжает работать без ошибок, даже если таблица не создана.

Это был действительно большой намек.

kailash gaur 09.05.2017 18:47

Убедитесь, что spring.jpa.database-platform = org.hibernate.dialect.MySQL5Dialect имеет правильную версию MySQL.

Другие вопросы по теме