wake-up-neo.com

Spring Boot + JPA: Anmerkung zum Spaltennamen ignoriert

Ich habe eine Spring Boot-Anwendung mit Abhängigkeit spring-boot-starter-data-jpa. Meine Entitätsklasse verfügt über eine Spaltenanmerkung mit einem Spaltennamen. Beispielsweise:

@Column(name="TestName")
private String testName;

Von diesem erzeugten SQL-Code wurde test_name Als Spaltenname erstellt. Nach der Suche nach einer Lösung habe ich festgestellt, dass spring.jpa.hibernate.naming_strategy=org.hibernate.cfg.EJB3NamingStrategy Das Problem behoben hat (der Spaltenname stammt aus der Spaltenanmerkung).

Meine Frage ist jedoch, warum JPA Spaltenanmerkungen ignoriert, wenn naming_strategy nicht auf EJB3NamingStrategy Gesetzt ist. Vielleicht hat der Dialekt des Winterschlafes etwas damit zu tun? Ich verbinde mich mit MS SQL 2014 Express und meine Protokolle enthalten:

Unknown Microsoft SQL Server major version [12] using SQL Server 2000 dialect
Using dialect: org.hibernate.dialect.SQLServerDialect 
108
Kamil

Für hibernate5 habe ich dieses Problem behoben, indem ich die nächsten Zeilen in meine application.properties-Datei geschrieben habe:

spring.jpa.hibernate.naming.implicit-strategy=org.hibernate.boot.model.naming.ImplicitNamingStrategyLegacyJpaImpl
spring.jpa.hibernate.naming.physical-strategy=org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
133
teteArg

Standardmäßig verwendet Spring org.springframework.boot.orm.jpa.SpringNamingStrategy, Um Tabellennamen zu generieren. Dies ist eine sehr dünne Erweiterung von org.hibernate.cfg.ImprovedNamingStrategy. Der Methode tableName in dieser Klasse wird ein Quellwert String übergeben, es ist jedoch nicht bekannt, ob sie aus einem Attribut @Column.name Stammt oder implizit aus dem Feldnamen generiert wurde.

Das ImprovedNamingStrategy konvertiert CamelCase in SNAKE_CASE, Wobei das EJB3NamingStrategy Nur den Tabellennamen unverändert verwendet.

Wenn Sie die Namensstrategie nicht ändern möchten, können Sie Ihren Spaltennamen immer in Kleinbuchstaben eingeben:

@Column(name="testname")
79
Phil Webb

Es scheint, dass

@Column (name = "..")

wird vollständig ignoriert, es sei denn

spring.jpa.hibernate.naming_strategy = org.hibernate.cfg.EJB3NamingStrategy

angegeben, also für mich ist dies ein Bug.

Ich habe ein paar Stunden damit verbracht herauszufinden, warum @Column (name = "..") ignoriert wurde.

31
ncaralicea

Die Standardstrategie für @Column(name="TestName") ist test_name, Dies ist korrektes Verhalten!

Wenn Ihre Datenbank eine Spalte mit dem Namen TestName enthält, sollten Sie die Spaltenanmerkung in @Column(name="testname") ändern.

Dies funktioniert, da es der Datenbank egal ist, ob Sie Ihre Spalte TestName oder Testname (Spaltennamen berücksichtigen nicht die Groß- und Kleinschreibung !!) benennen.

Beachten Sie jedoch, dass dies nicht für Datenbank- und Tabellennamen gilt, bei denen auf Unix-Systemen die Groß- und Kleinschreibung beachtet wird, bei Windows-Systemen jedoch die Groß- und Kleinschreibung :))

11
Orhan

Die einzige Lösung, die für mich funktioniert hat, war die von teteArg oben veröffentlichte. Ich bin auf Spring Boot 1.4.2 w/Hibernate 5. Nämlich

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

Für zusätzliche Informationen poste ich die Anrufverfolgung, damit klar ist, welche Anrufe Spring in den Ruhezustand leitet, um die Namensstrategie festzulegen.

      at org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl.toPhysicalColumnName(PhysicalNamingStrategyStandardImpl.Java:46)
  at org.hibernate.cfg.Ejb3Column.redefineColumnName(Ejb3Column.Java:309)
  at org.hibernate.cfg.Ejb3Column.initMappingColumn(Ejb3Column.Java:234)
  at org.hibernate.cfg.Ejb3Column.bind(Ejb3Column.Java:206)
  at org.hibernate.cfg.Ejb3DiscriminatorColumn.buildDiscriminatorColumn(Ejb3DiscriminatorColumn.Java:82)
  at org.hibernate.cfg.AnnotationBinder.processSingleTableDiscriminatorProperties(AnnotationBinder.Java:797)
  at org.hibernate.cfg.AnnotationBinder.bindClass(AnnotationBinder.Java:561)
  at org.hibernate.boot.model.source.internal.annotations.AnnotationMetadataSourceProcessorImpl.processEntityHierarchies(AnnotationMetadataSourceProcessorImpl.Java:245)
  at org.hibernate.boot.model.process.spi.MetadataBuildingProcess$1.processEntityHierarchies(MetadataBuildingProcess.Java:222)
  at org.hibernate.boot.model.process.spi.MetadataBuildingProcess.complete(MetadataBuildingProcess.Java:265)
  at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.metadata(EntityManagerFactoryBuilderImpl.Java:847)
  at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.Java:874)
  at org.springframework.orm.jpa.vendor.SpringHibernateJpaPersistenceProvider.createContainerEntityManagerFactory(SpringHibernateJpaPersistenceProvider.Java:60)
  at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.Java:353)
  at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.buildNativeEntityManagerFactory(AbstractEntityManagerFactoryBean.Java:373)
  at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.Java:362)
  at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.Java:1642)
  at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.Java:1579)
  at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.Java:553)
  at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.Java:482)
  at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.Java:306)
  at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.Java:230)
  - locked <0x1687> (a Java.util.concurrent.ConcurrentHashMap)
  at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.Java:302)
  at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.Java:197)
  at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.Java:1081)
  at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.Java:856)
  at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.Java:542)
  - locked <0x1688> (a Java.lang.Object)
  at org.springframework.boot.SpringApplication.refresh(SpringApplication.Java:761)
  at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.Java:371)
  at org.springframework.boot.SpringApplication.run(SpringApplication.Java:315)
  at org.springframework.boot.SpringApplication.run(SpringApplication.Java:1186)
  at org.springframework.boot.SpringApplication.run(SpringApplication.Java:1175)
9
Sanjiv Jivan

teteArg , vielen Dank. Nur eine zusätzliche Information, damit jeder, der auf diese Frage stößt, verstehen kann, warum.

Das teteArg Gesagte wird in den allgemeinen Spring Boot-Eigenschaften angegeben: http://docs.spring.io/spring-boot/docs/current/reference/html/common-application-properties) .html

Anscheinend ist spring.jpa.hibernate.naming.strategy keine unterstützte Eigenschaft für die Spring-JPA-Implementierung mit Hibernate 5.

6

Wenn Sie @Column (...) verwenden möchten, verwenden Sie immer Kleinbuchstaben, obwohl sich Ihre eigentliche DB-Spalte in Kamelbuchstaben befindet.

Beispiel: Wenn Ihr tatsächlicher DB-Spaltenname TestName ist, verwenden Sie:

  @Column(name="testname") //all small-case

Wenn Ihnen das nicht gefällt, ändern Sie einfach den tatsächlichen DB-Spaltennamen in: test_name

3
Dean

Es stellt sich heraus, dass ich nur den @column - Namen testName in alle Kleinbuchstaben umwandeln muss, da es sich ursprünglich um eine Kamelschreibweise handelte.

Obwohl ich die offizielle Antwort nicht verwenden konnte, konnte mir die Frage helfen, mein Problem zu lösen, indem sie mich wissen ließ, was ich untersuchen sollte.

Veränderung:

@Column(name="testName")
private String testName;

Zu:

@Column(name="testname")
private String testName;
1
Mohammad Cali

In meinem Fall befand sich die Annotation in der getter () -Methode anstelle des Felds selbst (portiert aus einer Legacy-Anwendung).

Auch in diesem Fall ignoriert Spring die Annotation, beschwert sich aber nicht. Die Lösung bestand darin, das Feld anstelle des Getters zu verschieben.

0
java-addict301