Spring Boot + JPA:忽略列名注释

时间:2014-08-13 09:55:05

标签: java hibernate jpa spring-boot

我有一个依赖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忽略列注释?也许hibernate方言与它有关?我正在连接到MS SQL 2014 Express,我的日志包含:

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

12 个答案:

答案 0 :(得分:121)

对于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

答案 1 :(得分:77)

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

ImprovedNamingStrategy会将CamelCase转换为SNAKE_CASE,因为EJB3NamingStrategy只会更改表格名称。

如果您不想更改命名策略,您可以随时指定小写的列名:

@Column(name="testname")

答案 2 :(得分:31)

似乎

  

@Column(名称=" ..&#34)

除非有

,否则

完全被忽略

  

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

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

我花了几个小时试图弄明白为什么@Column(名字=" ..")被忽略了。

答案 3 :(得分:10)

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

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

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

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

答案 4 :(得分:9)

对我有用的唯一解决方案是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)

答案 5 :(得分:6)

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

Spring Boot Common Properties:teteArg

表示http://docs.spring.io/spring-boot/docs/current/reference/html/common-application-properties.html所说的内容

显然,使用Hibernate 5的Spring JPA实现不支持 spring.jpa.hibernate.naming.strategy

答案 6 :(得分:3)

如果你想使用@Column(...),那么即使你的实际数据库列是驼峰式的,也要使用小写字母。

示例:如果您的实际数据库列名称为TestName,请使用:

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

如果您不喜欢,只需将实际的DB列名称更改为: TEST_NAME

答案 7 :(得分:3)

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

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

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

请记住,如果您在数据库中使用列名“ test_name”格式,则必须遵循以下方式

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

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

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

答案 8 :(得分:1)

我尝试了以上所有方法,但没有成功。这对我有用:

@Column(name="TestName")
public String getTestName(){//.........

注释吸气剂而不是变量

答案 9 :(得分:0)

在我的情况下,注释位于getter()方法上,而不是字段本身(从旧版应用程序移植)。

在这种情况下,Spring也会忽略注释,但不会抱怨。解决方案是将其移至字段而不是获取器。

答案 10 :(得分:0)

原来,我只是要将@column名称testName转换为所有小写字母,因为它最初是驼峰式的。

尽管我无法使用官方答案,但该问题通过让我知道要进行调查的内容能够帮助我解决问题。

更改:

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

收件人:

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

答案 11 :(得分:0)

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

@Column(name="\"gunName\"")
public String gunName;

具有属性:

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

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