简体   繁体   中英

Moving Spring Boot 1.3 to 1.4, Hibernate 4 to 5, Pascal Case Issues

I created a Spring Boot 1.3.5 POC with Spring Data JPA and Hibernate (4.3.11.Final in this version of Spring Boot). My backend database is Microsoft SQL Server, and our standard naming convention for database objects is pascal case (eg MySchema.MyTable.MyColumn). I used the javax.persistence.Table and javax.persistence.Column annotations to set the names, and added spring.jpa.hibernate.naming-strategy=org.hibernate.cfg.EJB3NamingStrategy to my application.properties file.

Everything worked perfectly. I even updated to Spring Boot 1.3.6 with no issues.

Now I moved to Spring Boot 1.4.0.RELEASE which uses Hibernate 5.0.9.Final, and the spring.jpa.hibernate.naming-strategy property is deprecated in favor of spring.jpa.hibernate.naming.strategy. I changed that property name, but left the EJB3NamingStrategy value. I also changed the other deprecated elements:

  • 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 (in my test classes)

Now the generated SQL uses the default camel case to underscore naming convention and not the pascal case that I had with 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
}

orignal console output:

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=?

new console output:

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

I've searched extensively, and found references to ImplicitNamingStrategy and PhysicalNamingStrategy; but plugging those in don't seem to work and is probably not the correct approach. I've also seen references to creating my own NamingStrategy. Is that the route I must take?

Is there a different setting for Hibernate 5 that will use the exact name I provide in the @Table and @Column annotations? Is there a problem with the way I am defining the annotations?

I would like to say I ended up posting a silly question, but every direction I went talked about creating a custom naming strategy. The answer in my case, however, was simply using Hibernate's PhysicalNamingStrategyStandardImpl.

Added to 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

From my naive analysis, I'm assuming this works because I am using the @Table and @Column annotations. The PhysicalNamingStrategyStandardImpl appears to simply use the name in those annotations as the database object name.

So my Hibernate generated query is once again formatted as:

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=?

Reading @AmanTuladhar's link and this link from that post is where it eventually clicked for me. Thanks!

this is really a nice thread , for a beginner - who are migrating from spring boot 1.3 to 1.4 - below link contains all the stranded changes required , it also list all the deprecated options and contains some examples as well .

It gives overview about almost everything that you can use with application. For ex- Hibernate , Log4j , Junit/Mockito , Integration and so on . Please follow below link

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM