【问题标题】:Moving Spring Boot 1.3 to 1.4, Hibernate 4 to 5, Pascal Case Issues将 Spring Boot 1.3 移至 1.4,将 Hibernate 4 移至 5,Pascal 案例问题
【发布时间】:2016-12-12 03:58:18
【问题描述】:

我使用 Spring Data JPA 和 Hibernate 创建了一个 Spring Boot 1.3.5 POC(此版本的 Spring Boot 中为 4.3.11.Final)。我的后端数据库是 Microsoft SQL Server,我们对数据库对象的标准命名约定是帕斯卡大小写(例如 MySchema.MyTable.MyColumn)。我使用 javax.persistence.Table 和 javax.persistence.Column 注释来设置名称,并将 spring.jpa.hibernate.naming-strategy=org.hibernate.cfg.EJB3NamingStrategy 添加到我的 application.properties 文件中。

一切都很完美。我什至毫无问题地更新到 Spring Boot 1.3.6。

现在我转移到使用 Hibernate 5.0.9.Final 的 Spring Boot 1.4.0.RELEASE,并且不推荐使用 spring.jpa.hibernate.naming-strategy 属性以支持 spring.jpa.hibernate.naming.strategy。我更改了该属性名称,但保留了 EJB3NamingStrategy 值。我还更改了其他已弃用的元素:

  • org.springframework.boot.orm.jpa.EntityScan 到 org.springframework.boot.autoconfigure.domain.EntityScan
  • org.springframework.boot.context.web.SpringBootServletInitializer 到 org.springframework.boot.web.support.SpringBootServletInitializer
  • org.springframework.boot.test.SpringApplicationConfiguration 到 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 注释中提供的确切名称? 我定义注释的方式有问题吗?

【问题讨论】:

标签: spring hibernate spring-data-jpa pascalcasing


【解决方案1】:

我想说我最终发布了一个愚蠢的问题,但我所去的每个方向都谈到了创建自定义命名策略。然而,就我而言,答案只是使用 Hibernate 的 PhysicalNamingStrategyStandardImpl。

添加到 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's linkthis link 是我最终点击的地方。谢谢!

【讨论】:

  • 这就是我需要的!非常感谢!
  • 这对我也有用,谢谢!奇怪的是,我的代码在本地环境中运行良好,但在 AWS EC2 Ubuntu 中运行时需要进行上述调整
【解决方案2】:

这确实是一个不错的线程,对于从 Spring Boot 1.3 迁移到 1.4 的初学者来说,下面的链接包含所有所需的搁浅更改,它还列出了所有不推荐使用的选项并包含一些示例。

它概述了您可以与应用程序一起使用的几乎所有内容。对于前 Hibernate、Log4j、Junit/Mockito、Integration 等。请点击以下链接

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多