2017-01-28 122 views
7

这让我很生气。Spring Boot休眠5忽略@Table和@Column

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

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

该注释被忽略,表被创建为user_connection,然后导致Spring社会有一个hissy适合。

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

+0

你如何配置你的汽车DDL创造? –

+0

也会很好,如果你添加你添加到sessionFactory的application.properties和proerties –

回答

5

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启动1.4 release notes状态:

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 

注释被忽略,表将创建为user_connection 然后使弹簧社会有嘘声像契合。

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

+0

我尝试了很多东西,但我失去了踪迹。我相信当我使用这种方法时,没有明确映射为使用下划线的所有其他表和列都是使用骆驼案例重新创建的。所以基本上,如果我使用这种方法,我将不得不遍历每一个列和表,并添加注释,并用下划线符号覆盖它们。 – Trevor

+0

是的,我刚刚测试过它,它的行为如上所述。所有未使用@Column和@Table命名的表和列都将在数据库中以驼峰大小形式创建。这很糟糕,因为我想要的是完全相反的效果。我只想明确地映射这个愚蠢的'UserConnection'表,而不是我所有的其他表和列。 – Trevor

+0

@Trevor然后你应该提供你自己的'ImplicitNamingStrategy' –

0

选项1

首先定义对@Entity映射你的表名:

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

选项2

你应该付一点与NamingStrategy。当你定义为SessionFactory豆你的属性然后尝试添加此:

<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