Spring Boot Hibernate 5忽略@Table和@Column
这让我很生气。
我正在实现Spring Social,它要求您拥有一个名为UserConnection
的数据库表(而不是使用使用下划线分隔这两个单词的标准命名约定)。
所以在我天真的世界观中,我认为通过指定@Table(name="UserConnection")
可以很容易地解决这个问题……但不,这太容易了。
注释被忽略,表被创建为user_connection
,然后导致Spring Social有一个合适的东西。
请告诉我有一些简单的方法告诉我的Spring Boot应用程序只是命名一个表(及其相应的列)以使用camel-case命名约定而不是标准约定。
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 发行说明所述:
由于Hibernate 5.1已经删除了对旧
NamingStrategy
接口的支持,因此不再使用SpringNamingStrategy
。 现在自动配置了一个新的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
注释被忽略,表被创建为
user_connection
,然后导致Spring Social有一个合适的东西。
SpringPhysicalNamingStrategy
的apply
方法是理解这种行为的关键:
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定义属性时,请尝试添加以下内容:
legacy-jpa
当实体没有显式命名它映射到的数据库表时,我们需要隐式确定该表名。 或者,当某个特定属性没有显式命名它映射到的数据库列时,我们需要隐式确定该列名。
因此,如果您不想为每个实体明确命名您的表名,则应遵循此策略。
选项3
或者,如果上述方法不适合您,则必须使用PhysicalNamingStrategy。 虽然这是您案例中的最后手段:
参考: https ://docs.jboss.org/hibernate/orm/5.1/userguide/html_single/chapters/domain/naming.html