Spring Boot Hibernate 5忽略@Table和@Column

Tre*_*vor 9 java spring-social spring-boot hibernate-5.x

这让我很生气.

我正在实现Spring Social,它要求你有一个名为的数据库表UserConnection(而不是使用使用下划线分隔这两个单词的标准命名约定).

因此,在我天真的世界观中,我认为通过指定@Table(name="UserConnection")...... 很容易解决,但不会,这太简单了.

注释被忽略,并创建表格user_connection,然后使Spring Social具有合适的效果.

请告诉我有一些简单的方法告诉我的Spring Boot应用程序只是命名一个表(及其相应的列)以使用驼峰式命名约定而不是标准约定.

Ali*_*ani 10

TL; DR

将以下内容添加到您的application.yml文件中:

spring:
  jpa:
    hibernate:
      naming:
        physical-strategy: org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
Run Code Online (Sandbox Code Playgroud)

或者你的application.properties:

spring.jpa.hibernate.naming.physical-strategy=org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
Run Code Online (Sandbox Code Playgroud)

详细解答

正如Spring Boot 1.4 发行说明所述:

SpringNamingStrategy不再使用,因为Hibernate 5.1已经删除了对旧NamingStrategy接口的支持.SpringPhysicalNamingStrategy现在自动配置了一个新的 ,它与Hibernate的默认值结合使用ImplicitNamingStrategy.这应该与Spring Boot 1.3默认值非常接近(如果不相同),但是,升级时应该检查数据库模式是否正确.

这个新的PhysicalNamingStrategy遵循Spring推荐的命名约定.无论如何,如果你想要完全控制物理命名,你最好使用org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl.您可以通过在以下内容中添加以下内容来切换到该命名策略application.yml:

spring:
  jpa:
    hibernate:
      naming:
        physical-strategy: org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
Run Code Online (Sandbox Code Playgroud)

注释被忽略,并创建表格user_connection ,然后使Spring Social具有合适的效果.

该apply方法SpringPhysicalNamingStrategy是了解这种行为的关键:

private Identifier apply(Identifier name, JdbcEnvironment jdbcEnvironment) {
    if (name == null) {
        return null;
    }
    StringBuilder builder = new StringBuilder(name.getText().replace('.', '_'));
    for (int i = 1; i < builder.length() - 1; i++) {
        if (isUnderscoreRequired(builder.charAt(i - 1), builder.charAt(i),
                builder.charAt(i + 1))) {
            builder.insert(i++, '_');
        }
    }
    return getIdentifier(builder.toString(), name.isQuoted(), jdbcEnvironment);
}

private boolean isUnderscoreRequired(char before, char current, char after) {
    return Character.isLowerCase(before) && Character.isUpperCase(current)
            && Character.isLowerCase(after);
}
Run Code Online (Sandbox Code Playgroud)

它基本上用下划线替换任何.和大小写更改(看一下isUnderscoreRequired方法).