Перемещение Spring Boot с 1.3 до 1.4, Hibernate 4 до 5, проблемы с Pascal

Я создал POC Spring Boot 1.3.5 с Spring Data JPA и Hibernate (4.3.11. Окончательный вариант в этой версии Spring Boot). Моя внутренняя база данных - Microsoft SQL Server, а наше стандартное соглашение об именах для объектов базы данных - случай Паскаля (например, MySchema.MyTable.MyColumn). Я использовал аннотации javax.persistence.Table и javax.persistence.Column для установки имен и добавил в свой файл application.properties spring.jpa.hibernate.naming-стратегии =org.hibernate.cfg.EJB3NamingStrategy.

Все работало отлично. Я даже обновился до Spring Boot 1.3.6 без проблем.

Теперь я перешел на Spring Boot 1.4.0.RELEASE, который использует Hibernate 5.0.9.Final, а свойство spring.jpa.hibernate.naming-стратегии устарело в пользу spring.jpa.hibernate.naming.strategy. Я изменил это имя свойства, но оставил значение EJB3NamingStrategy. Я также изменил другие устаревшие элементы:

  • org.springframework.boot.orm.jpa.EntityScan to org.springframework.boot.autoconfigure.domain.EntityScan
  • org.springframework.boot.context.web.SpringBootServletInitializer to org.springframework.boot.web.support.SpringBootServletInitializer
  • org.springframework.boot.test.SpringApplicationConfiguration to org.springframework.boot.test.context.SpringBootTest (в моих тестовых классах)

Теперь сгенерированный SQL использует случай верблюда по умолчанию, чтобы подчеркнуть соглашение об именах, а не случай Паскаля, который я имел с EJB3NamingStrategy.

//application.properties
spring.data.jpa.repositories.enabled=true
spring.data.solr.repositories.enabled=false
spring.data.mongodb.repositories.enabled=false
spring.datasource.driver-class-name=com.microsoft.sqlserver.jdbc.SQLServerDriver
spring.jpa.hibernate.naming.strategy=org.hibernate.cfg.EJB3NamingStrategy
#spring.jpa.hibernate.naming-strategy=org.hibernate.cfg.EJB3NamingStrategy

//hibernate.properties
hibernate.dialect=org.hibernate.dialect.SQLServer2012Dialect
hibernate.format_sql=true

//Principal.java
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.validation.constraints.Size;

import org.hibernate.envers.AuditTable;
import org.hibernate.envers.Audited;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@Entity
@Table(name="Principal", schema="Security")
@Audited
@AuditTable(value = "Principal", schema = "Audit")
public class Principal {

    private static final Logger LOG = LoggerFactory.getLogger(Principal.class);

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "Id", 
            nullable = false)
    private Long id;

    @Column(name = "Username", 
            nullable = false, 
            unique = true)
    @Size(min = 1, max = 64)
    private String name;

    @Column(name = "FirstName", 
            nullable = false)
    @Size(min = 1, max = 64)
    private String firstName;

    @Column(name = "LastName", 
            nullable = false)
    @Size(min = 1, max = 128)
    private String lastName;

    @Column(name = "IsEnabled", 
            nullable = false)
    private boolean enabled;

    //getters/setters omitted for brevity
}

оригинальный вывод консоли:

Hibernate: 
    select
        principal0_.Id as Id1_8_,
        principal0_.IsEnabled as IsEnable2_8_,
        principal0_.FirstName as FirstNam3_8_,
        principal0_.LastName as LastName4_8_,
        principal0_.Username as Username5_8_ 
    from
        Security.Principal principal0_ 
    where
        principal0_.Username=?

новый консольный вывод:

Hibernate: 
    select
        principal0_.id as id1_7_,
        principal0_.is_enabled as is_enabl2_7_,
        principal0_.first_name as first_na3_7_,
        principal0_.last_name as last_nam4_7_,
        principal0_.username as username5_7_ 
    from
        security.principal principal0_ 
    where
        principal0_.username=?
2016-08-05 09:19:22.751  WARN 5032 --- [  XNIO-2 task-8] o.h.engine.jdbc.spi.SqlExceptionHelper   : SQL Error: 207, SQLState: S0001
2016-08-05 09:19:22.751 ERROR 5032 --- [  XNIO-2 task-8] o.h.engine.jdbc.spi.SqlExceptionHelper   : Invalid column name 'is_enabled'.
2016-08-05 09:19:22.768 ERROR 5032 --- [  XNIO-2 task-8] io.undertow.request                      : UT005023: Exception handling request to /springbootsecurity/login

Я много искал и нашел ссылки на ImplicitNamingStrategy и PhysicalNamingStrategy; но подключение этих устройств, похоже, не работает и, вероятно, не является правильным подходом. Я также видел ссылки на создание моей собственной NamingStrategy. Это тот путь, по которому я должен идти?

Существуют ли другие настройки для Hibernate 5, в которых будет использоваться точное имя, указанное в аннотациях @Table и @Column? Есть ли проблема с тем, как я определяю аннотации?

2 ответа

Я хотел бы сказать, что закончил тем, что опубликовал глупый вопрос, но каждое направление, о котором я говорил, говорило о создании собственной стратегии именования. Однако в моем случае ответом было просто использование PhysicalNamingStrategyStandardImpl от Hibernate.

Добавлено в application.properties:

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

Исходя из моего наивного анализа, я предполагаю, что это работает, потому что я использую аннотации @Table и @Column. Похоже, что PhysicalNamingStrategyStandardImpl просто использует имя в этих аннотациях в качестве имени объекта базы данных.

Таким образом, мой сгенерированный запрос Hibernate снова отформатирован как:

Hibernate: 
    select
        principal0_.Id as Id1_7_,
        principal0_.IsEnabled as IsEnable2_7_,
        principal0_.FirstName as FirstNam3_7_,
        principal0_.LastName as LastName4_7_,
        principal0_.Username as Username5_7_ 
    from
        Security.Principal principal0_ 
    where
        principal0_.Username=?

Чтение ссылки @AmanTuladhar и этой ссылки из этого поста, где она в конечном итоге щелкнула для меня. Спасибо!

Это действительно хорошая тема, для начинающих - которые переходят с весенней загрузки с 1.3 на 1.4 - ссылка ниже содержит все требуемые изменения, она также перечисляет все устаревшие параметры и содержит некоторые примеры.

Он дает обзор почти всего, что вы можете использовать с приложением. Для бывшего Hibernate, Log4j, Junit/Mockito, Интеграция и так далее. Пожалуйста, перейдите по ссылке ниже

https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-1.4-Release-Notes

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