Spring Boot + JPA:忽略列名注释

Kam*_*mil 111 java hibernate jpa spring-boot

我有一个依赖的Spring Boot应用程序spring-boot-starter-data-jpa.我的实体类有一个带有列名的列注释.例如:

@Column(name="TestName")
private String testName;
Run Code Online (Sandbox Code Playgroud)

由此生成的SQL创建test_name为列名.在寻找解决方案后,我发现spring.jpa.hibernate.naming_strategy=org.hibernate.cfg.EJB3NamingStrategy解决了问题(列名取自列注释).

不过,我的问题是为什么没有设置为EJB3NamingStrategyJPA的naming_strategy 忽略列注释?也许hibernate方言与它有关?我正在连接到MS SQL 2014 Express,我的日志包含:

Unknown Microsoft SQL Server major version [12] using SQL Server 2000 dialect
Using dialect: org.hibernate.dialect.SQLServerDialect 
Run Code Online (Sandbox Code Playgroud)

tet*_*Arg 140

对于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
Run Code Online (Sandbox Code Playgroud)

  • spring.jpa.hibernate.naming.physical-strategy = org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl,只需要这个属性来保持名称不变. (23认同)

Phi*_*ebb 81

默认情况下,Spring用于org.springframework.boot.orm.jpa.SpringNamingStrategy生成表名.这是一个非常薄的扩展org.hibernate.cfg.ImprovedNamingStrategy.tableName该类中的方法是传递给源String值的,但如果它来自某个@Column.name属性,或者它是从字段名称隐式生成的,则它不知道.

ImprovedNamingStrategy会转换CamelCaseSNAKE_CASE其中的EJB3NamingStrategy只是使用表名不变.

如果您不想更改命名策略,则始终只需以小写字母指定列名:

@Column(name="testname")
Run Code Online (Sandbox Code Playgroud)


nca*_*cea 31

看起来

@Column(名称= "..")

除非有,否则完全被忽略

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

指定,所以对我来说这是一个错误.

我花了几个小时试图找出为什么@Column(name ="..")被忽略了.

  • 我有同样的问题.我在这里添加了一个问题报告:https://github.com/spring-projects/spring-boot/issues/2129 (4认同)

Orh*_*han 12

@Column(name="TestName")将是默认策略test_name,这是正确的行为!

如果TestName在数据库中有一个列,则应将Column注释更改为@Column(name="testname").

这是有效的,因为数据库不关心您是否将列命名为 TestName或testname(列名称不区分大小写!!).

但要注意,同样不适用于数据库名称和表名,在Unix系统上是区分大小写的,但在Windows系统上是敏感的(事实上可能让很多人在晚上醒来,在Windows上工作但在Linux上部署:))

  • 1.事实并非如此,列名称可能区分大小写,具体取决于您所使用的数据库的配置... 2. @列名称-顾名思义,该名称应该是提供数据库列名称的位置,而不是框架提供的某些标识符将在运行时更改。 (3认同)
  • 1.对不起,我不能,因为我不在乎默认情况下有哪个设置,我在乎DBA在我正在使用的设置上设置了哪些设置。2.不幸的是,这是正确的-这只是我个人的看法,因为这种方法是错误的,因为它迫使我思考或思考名称将如何最终映射到列,或者使用哪种命名策略不会影响提供的名称。 (2认同)

San*_*van 10

对我有用的唯一解决方案是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
Run Code Online (Sandbox Code Playgroud)

为了获得更多的洞察力,我发布了调用跟踪,以便清楚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)
Run Code Online (Sandbox Code Playgroud)


小智 7

我也尝试了以上所有方法,但没有任何效果。我在数据库中得到了名为“gunName”的字段,但我无法处理这个问题,直到我使用了下面的示例:

@Column(name="\"gunName\"")
public String gunName;
Run Code Online (Sandbox Code Playgroud)

具有以下属性:

spring.jpa.hibernate.naming.implicit-strategy=org.hibernate.boot.model.naming.ImplicitNamingStrategyLegacyJpaImpl
spring.jpa.hibernate.naming.physical-strategy=org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
Run Code Online (Sandbox Code Playgroud)

另请参阅: https: //stackoverflow.com/a/35708531


Rom*_*nan 6

teteArg,非常感谢你.只是一个附加的信息,所以每个人都能够理解为什么.

什么teteArg说,在春季启动通用属性表示: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名称 testName转换为所有小写字母,因为它最初是驼峰式的。

虽然我无法使用官方答案,但该问题通过让我知道要调查的内容来帮助我解决问题。

改变:

@Column(name="testName")
private String testName;
Run Code Online (Sandbox Code Playgroud)

到:

@Column(name="testname")
private String testName;
Run Code Online (Sandbox Code Playgroud)


小智 5

当你使用 spring jpa 时,你必须遵循一些命名策略。列名应为小写或大写。

@Column(name="TESTNAME")
private String testName;
Run Code Online (Sandbox Code Playgroud)

或者

@Column(name="testname")
private String testName;
Run Code Online (Sandbox Code Playgroud)

请记住,如果数据库中有列名“test_name”格式,那么您必须遵循以下方式

@Column(name="TestName")
private String testName;
Run Code Online (Sandbox Code Playgroud)

或者

@Column(name="TEST_NAME")
private String testName;
Run Code Online (Sandbox Code Playgroud)

或者

@Column(name="test_name")
private String testName;
Run Code Online (Sandbox Code Playgroud)