春靴冬眠5忽略@Table和@ColumnTL;博士 详细答案

这让我发疯。

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

因此,在我天真的世界观中,我以为通过指定...但是不,那太容易了。@Table(name="UserConnection")

注释将被忽略并创建表,然后导致Spring Social具有嘶嘶声。user_connection

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


答案 1

TL;博士

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

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

或您的 :application.properties

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

详细答案

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

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

这个新功能遵循了Spring推荐的命名约定。无论如何,如果您想完全控制物理命名,最好使用 .您可以通过将以下内容添加到您的PhysicalNamingStrategyorg.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImplapplication.yml

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

注释将被忽略并创建表,然后导致Spring Social具有嘶嘶声。user_connection

的 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);
}

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


答案 2

备选案文1

首先,在@Entity映射上定义表名:

@Entity( name = "UserConnections")
public class UserConnection{

备选案文2

您应该使用命名策略支付一点费用。当您为 sessionFactory Bean 定义属性时,请尝试添加以下内容:

<prop key="hibernate.implicit_naming_strategy">legacy-jpa</prop>

当实体未显式命名它映射到的数据库表时,我们需要隐式确定该表名。或者,当特定属性未显式命名它映射到的数据库列时,我们需要隐式确定该列名。

因此,如果您不想为每个实体显式命名表名,则应遵循此策略。

备选案文3

或者,如果上述方法对您不起作用,则必须使用物理命名策略。虽然这是您情况下的最后手段:

引用: https://docs.jboss.org/hibernate/orm/5.1/userguide/html_single/chapters/domain/naming.html


推荐