Spring Boot Hibernate 5 Ignoring @Table and @Column



这让我抓狂。

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

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

注释被忽略,表被创建为user_connection,这会导致Spring Social出现嘶嘶声。

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

TL;DR

将以下内容添加到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已删除支持旧的NamingStrategy接口。新的SpringPhysicalNamingStrategy现在已自动配置,用于与Hibernate的默认CCD_ 9的组合。这应非常接近(如果不相同)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

注释被忽略,表被创建为user_connection这导致Spring Social发出嘶嘶声。

SpringPhysicalNamingStrategyapply方法是理解这种行为的关键:

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方法)。

选项1

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

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

选项2

你应该为NamingStrategy付出一点代价。当您为sessionFactory bean定义属性时,请尝试添加以下内容:

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

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

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

选项3

或者,如果以上不适用于您,您必须使用PhysicalNamingStrategy。尽管这是你的最后手段:

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

最新更新