2017-01-28 18 views
7

To doprowadza mnie do szału.Spring Boot Hibernate 5 Ignoring @Table i @Column

Wdrażam Spring Social i wymaga ona posiadania tabeli bazy danych o nazwie UserConnection (zamiast używania standardowej konwencji nazewnictwa z użyciem podkreślenia w celu oddzielenia dwóch słów).

W moim naiwnym światopoglądzie założyłem, że można go łatwo rozwiązać, podając @Table(name="UserConnection") ... ale nie, to byłoby zbyt łatwe.

Adnotacja jest ignorowana, a tabela jest tworzona jako user_connection, co powoduje, że Spring Social ma hissy fit.

Poinformuj mnie, że istnieje prosty sposób, aby powiedzieć mojej aplikacji Spring Boot, aby nazwał tylko tę tabelę (i odpowiadające jej kolumny), aby użyć konwencji nazewnictwa wielbłądów zamiast standardowej.

+0

jaki sposób skonfigurować automatyczne tworzenie ddl? –

+0

również byłby dobry, gdyby dodać właściwości application.properties i właściwości dodane do obiektu sessionFactory –

Odpowiedz

5

TL; DR

dodać następujące do pliku application.yml:

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

Lub application.properties:

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

szczegółową odpowiedź

Jako wiosennej Boot 1.4 release notes stany:

SpringNamingStrategy nie jest już używany jako Hibernuj 5.1 usunął obsługę dla starego interfejsu NamingStrategy. Nowy SpringPhysicalNamingStrategy jest teraz skonfigurowany automatycznie, który jest używany w kombinacji z domyślnym ImplicitNamingStrategy Hibernate. Ten powinien być bardzo bliski (jeśli nie identyczny) do domyślnych ustawień Spring Boot 1.3 , jednak podczas aktualizacji należy sprawdzić, czy schemat bazy danych jest poprawny .

Ten nowy PhysicalNamingStrategy jest zgodny z zalecanymi konwencjami nazewnictwa Spring. W każdym razie, jeśli chcesz mieć całkowitą kontrolę nad fizycznym nazywaniem, lepiej jest korzystać z org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl. można przełączyć się na tej strategii nazewnictwa przez dodanie następujących do Twojego application.yml:

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

Adnotacja jest ignorowany, a tabela jest tworzona jako user_connection które następnie powoduje Wiosna Social mieć hissy dopasowanie.

apply metoda SpringPhysicalNamingStrategy jest kluczem do zrozumienia tego zachowania:

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

To w zasadzie zastępuje wszelkie . oraz sprawa zmiany (Spójrz na isUnderscoreRequired metody), z podkreśleniem.

+0

Próbowałem tak wielu rzeczy, że zgubiłem trop. Sądzę, że gdy użyłem tej metody, wszystkie inne tabele i kolumny, które nie zostały jawnie zamapowane przy użyciu podkreśleń, zostały odtworzone przy użyciu wielbłąda. Zasadniczo, jeśli zastosuję to podejście, będę musiał przejść przez każdą kolumnę i tabelę oraz dodać adnotacje, które nadpisują je notacją podkreślenia. – Trevor

+0

Tak, właśnie wypróbowałem to i to zachowuje się jak wyżej. Wszystkie tabele i kolumny, które nie są jawnie nazwane przez @Column i @Table, zostaną utworzone w DB jako wielka skrzynka. To jest do bani, ponieważ chcę mieć dokładnie odwrotny efekt. Chcę TYLKO wyraźnie wymapować tę jedną głupią tabelę "UserConnection", nie wszystkie moje pozostałe tabele i kolumny. – Trevor

+0

@Trevor Następnie należy podać własną 'ImplicitNamingStrategy' –

0

Wariant 1

Przede wszystkim zdefiniowanie nazwy tabel na mapowaniu @Entity:

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

Wariant 2

Trzeba zapłacić trochę z NamingStrategy. Podczas definiowania właściwości dla SessionFactory fasoli następnie spróbuj dodać to:

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

gdy jednostka nie jawnie nazwę tabeli bazy danych, które go do mapy, musimy ustalić, że niejawnie nazwę tabeli. Lub gdy konkretny atrybut nie jawnie nazwać kolumna bazy danych, że to mapuje, musimy domyślnie określić tę nazwę kolumny.

Jeśli więc nie chcesz jednoznacznie nazwać nazw tabel dla każdej z nich, powinieneś zastosować się do tej strategii.

Wariant 3

Ewentualnie jeśli powyższe nie działa, trzeba użyć PhysicalNamingStrategy. Choć jest ostatecznością w przypadku:

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