Spring boot JPA insert в TABLE с именем верхнего регистра с Hibernate

У меня есть объект таблицы, отображаемый как:

@Entity
public class ItemsToRegister implements Serializable{

@Id
@Column(name = "ID_ITEM_TO_REGISTER")
@GeneratedValue(strategy = GenerationType.AUTO)
private int id;
.....

Когда я пытаюсь вставить новую запись в базу данных, имя таблицы было переведено в нижнем регистре как: items_to_register, но мое имя таблицы - ITEMS_TO_REGISTER Как я могу исправить свою проблему без изменения конфигурации MySql? (my.cnf)

У меня в файле application.properties:

spring.jpa.hibernate.dialect = org.hibernate.dialect.MySQL5Dialect
spring.jpa.hibernate.naming_strategy = org.hibernate.cfg.ImprovedNamingStrategy

Ответ 1

В спящем режиме 5 это будет

spring.jpa.hibernate.naming.physical-strategy=org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl

в файле application.properties.

Ответ 2

Решение, которое оно добавляет:

spring.jpa.hibernate.naming_strategy = org.hibernate.cfg.EJB3NamingStrategy

для application.properties:)

Да!!!

Ответ 3

Вам нужно будет избежать имени таблицы с тиками (`), чтобы сделать регистр чувствительным к регистру.

@Table(name = "`ITEMS_TO_REGISTER`")

Ответ 4

Как предположил @jasonleakey, мы можем рассмотреть возможность использования стратегии именования, как показано ниже.

spring.jpa.hibernate.naming.physical-strategy=org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl

это говорит Hibernate генерировать SQL точно так, как указано в @Table (name= ") или @Column (name=" "). Все хорошо.

Но имейте в виду - при использовании PhysicalNamingStrategy без @Table, аннотации @Column в классе сущности, hibernate генерирует SQL, используя имена классов и имена переменных. Рассмотрим ниже класс java

Class Employee {
   private String firstName;
   private String lastName; 
}

то сгенерированный sql будет,

select employee0_.firstName,employee0_lastName from Employee employee0_;

К сожалению, это не отличный выбор, поскольку мы обычно определяли бы столбцы в БД как FIRST_NAME и LAST_NAME, а имя таблицы - как EMPLOYEE. Если бы вы не использовали PhysicalNamingStrategy, SQL был бы

select employee0_.first_name,employee0_last_name from employee employee0_;

так что это действительно выбор между двумя нижеуказанными вариантами.

  • Использование PhysicalStrategy и явное определение имен таблиц и имен столбцов в java-коде с помощью @Table и @Column аннотаций.
    или
  • Определите имя нижней таблицы в db и дайте hibernate автоматически генерировать имена таблиц/имена столбцов для нас.

Ответ 5

Вы можете попробовать:

@Entity
@Table(name = "ITEMS_TO_REGISTER")
public class ItemsToRegister implements Serializable {
   ...

Ответ 6

Вы можете реализовать свою собственную стратегию и вызвать ее из application.properties:

spring.jpa.hibernate.naming.physical-strategy=com.proto.CustomPhysicalNamingStrategy

Ниже приведен пример, в котором всегда используется первая буква

import java.io.Serializable;
import org.apache.commons.lang3.StringUtils;
import org.hibernate.boot.model.naming.Identifier;
import org.hibernate.boot.model.naming.PhysicalNamingStrategy;
import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment;

public class CustomPhysicalNamingStrategy implements PhysicalNamingStrategy, Serializable {
    /**
     * Singleton access
     */
    public static final CustomPhysicalNamingStrategy INSTANCE = new CustomPhysicalNamingStrategy();

    @Override
    public Identifier toPhysicalCatalogName(Identifier name, JdbcEnvironment context) {
        return capitalize(name);
    }

    @Override
    public Identifier toPhysicalSchemaName(Identifier name, JdbcEnvironment context) {
        return capitalize(name);
    }

    @Override
    public Identifier toPhysicalTableName(Identifier name, JdbcEnvironment context) {
        return capitalize(name);
    }

    @Override
    public Identifier toPhysicalSequenceName(Identifier name, JdbcEnvironment context) {
        return capitalize(name);
    }

    @Override
    public Identifier toPhysicalColumnName(Identifier name, JdbcEnvironment context) {
        return capitalize(name);
    }

    private Identifier capitalize(Identifier name) {
        if (name == null)
            return null;
        if (name.isQuoted())
            return name;
        String text = StringUtils.capitalize(name.getText());
        return Identifier.toIdentifier(text);
    }
}