首页 文章

Spring Boot JPA:忽略列名注释

提问于
浏览
87

我有一个依赖 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

8 回答

  • 6

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

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

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

    这是有效的,因为数据库不关心您是否将列命名为TestName或testname( column names are case insensitive!! ) .

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

  • 99

    看起来

    @Column(name =“..”)

    除非有,否则完全被忽略

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

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

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

  • 3

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

    teteArg所说的内容在Spring Boot Common Properties上显示:http://docs.spring.io/spring-boot/docs/current/reference/html/common-application-properties.html

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

  • 9

    如果你想使用@Column(...),那么即使你的实际DB列是camel-case,也要使用小写字母 .

    示例:如果您的实际数据库列名是 TestName ,则使用:

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

    如果您不喜欢这样,那么只需将实际的DB列名称更改为:test_name

  • 6

    对我有用的唯一解决方案是teteArg上面发布的解决方案 . 我正在使用Hibernate 5的Spring Boot 1.4.2 . 即

    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)
    
  • 4

    唯一对我有用的是上面发布的两行代码:

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

    只有ncaralicea提出的单行不适合我

  • 31

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

    ImprovedNamingStrategyCamelCase 转换为 SNAKE_CASE ,因为 EJB3NamingStrategy 只是使用表名不变 .

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

    @Column(name="testname")
    

相关问题