2017-01-28 152 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