web-dev-qa-db-ja.com

Spring Boot + JPA:列名の注釈は無視されます

依存関係spring-boot-starter-data-jpaのSpring Bootアプリケーションがあります。エンティティクラスには、列名を持つ列注釈があります。例えば:

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

これによって生成されたSQLは、列名としてtest_nameを作成しました。解決策を探した後、spring.jpa.hibernate.naming_strategy=org.hibernate.cfg.EJB3NamingStrategyが問題を解決したことがわかりました(列名は列注釈から取られています)。

それでも、naming_strategyをEJB3NamingStrategyに設定せずにJPAが列注釈を無視するのはなぜですか?休止状態の方言は何か関係があるのでしょうか? MS SQL 2014 Expressに接続していますが、ログに次の内容が含まれています:

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

Hibernate5の場合、application.propertiesファイルに次の行を追加してこの問題を解決しました。

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

デフォルトでは、Springはorg.springframework.boot.orm.jpa.SpringNamingStrategyを使用してテーブル名を生成します。これは、org.hibernate.cfg.ImprovedNamingStrategyの非常に薄い拡張です。そのクラスのtableNameメソッドにはソースString値が渡されますが、それが@Column.name属性に由来する場合、またはフィールド名から暗黙的に生成された場合は認識されません。

ImprovedNamingStrategyCamelCaseSNAKE_CASEに変換します。ここで、EJB3NamingStrategyはテーブル名をそのまま使用します。

命名戦略を変更したくない場合は、常に小文字で列名を指定できます。

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

のようだ

@Column(name = "..")

存在しない限り、完全に無視されます

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

指定されているので、私にとってこれはバグです。

@Column(name = "..")が無視された理由を理解しようとして数時間を費やしました。

31
ncaralicea

@Column(name="TestName")のデフォルト戦略はtest_nameになります。これは正しい動作です!

データベースにTestNameという名前の列がある場合、列注釈を@Column(name="testname")に変更する必要があります。

これは、列にTestNameまたはtestnameという名前を付けてもデータベースが気にしないためです(列名は大文字と小文字を区別しません!!)。

ただし、Unixシステムでは大文字と小文字が区別されますが、Windowsシステムでは大文字と小文字が区別されるデータベース名とテーブル名には同じことが当てはまりません:))

11
Orhan

私のために働いた唯一の解決策は、上記のteteArgによって投稿されたものでした。 Spring Boot 1.4.2 w/Hibernate 5を使用しています。

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

追加の洞察のために、SpringがHibernateに名前付け戦略を設定するために呼び出しているものが明確になるように、呼び出しトレースを投稿しています。

      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 、ありがとうございました。追加情報なので、この質問にぶつかった人は誰でもその理由を理解できます。

teteArg が言ったことは、Spring Bootの共通プロパティに示されています: http://docs.spring.io/spring-boot/docs/current/reference/html/common-application-properties .html

明らかに、spring.jpa.hibernate.naming.strategyは、Hibernate 5を使用したSpring JPA実装でサポートされているプロパティではありません。

6

@Column(...)を使用する場合は、実際のDB列がキャメルケースであっても、常に小文字を使用します。

例:実際のDB列名がTestNameの場合、次を使用します。

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

気に入らない場合は、実際のDB列名をtest_nameに変更するだけです

3
Dean

@column name testNameをすべて小文字に変換する必要があることがわかりました。最初はラクダの場合でした。

公式の回答を使用することはできませんでしたが、この質問は、調査対象を知らせることで問題の解決に役立ちました。

変化する:

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

に:

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

私の場合、注釈はフィールド自体(従来のアプリケーションから移植された)ではなくgetter()メソッドにありました。

この場合もSpringは注釈を無視しますが、文句は言いません。解決策は、ゲッターではなくフィールドに移動することでした。

0
java-addict301