Java Spring Boot + JPA:列名注释被忽略
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/25283198/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Spring Boot + JPA : Column name annotation ignored
提问by Kamil
I have a Spring Boot application with dependency spring-boot-starter-data-jpa
. My entity class has a column annotation with a column name. For example:
我有一个具有依赖项的 Spring Boot 应用程序spring-boot-starter-data-jpa
。我的实体类有一个带有列名的列注释。例如:
@Column(name="TestName")
private String testName;
SQL generated by this created test_name
as the columns name. After looking for a solution I have found that spring.jpa.hibernate.naming_strategy=org.hibernate.cfg.EJB3NamingStrategy
solved the problem (column name is taken from column annotation).
由此生成的 SQLtest_name
作为列名创建。在寻找解决方案后,我发现spring.jpa.hibernate.naming_strategy=org.hibernate.cfg.EJB3NamingStrategy
解决了问题(列名取自列注释)。
Still, my question is why without naming_strategy set to EJB3NamingStrategy
JPA is ignoring column annotation? Maybe hibernate dialect has something to do with it? I'm connecting to MS SQL 2014 Express and my logs contain:
不过,我的问题是为什么没有将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
采纳答案by teteArg
For hibernate5 I solved this issue by puting next lines in my application.properties file:
对于 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
回答by Phil Webb
By default Spring uses org.springframework.boot.orm.jpa.SpringNamingStrategy
to generate table names. This is a very thin extension of org.hibernate.cfg.ImprovedNamingStrategy
. The tableName
method in that class is passed a source String
value but it is unaware if it comes from a @Column.name
attribute or if it has been implicitly generated from the field name.
默认情况下,Spring 使用org.springframework.boot.orm.jpa.SpringNamingStrategy
生成表名。这是org.hibernate.cfg.ImprovedNamingStrategy
. tableName
该类中的方法传递了一个源String
值,但它不知道它是来自@Column.name
属性还是从字段名称隐式生成。
The ImprovedNamingStrategy
will convert CamelCase
to SNAKE_CASE
where as the EJB3NamingStrategy
just uses the table name unchanged.
该ImprovedNamingStrategy
会转换CamelCase
到SNAKE_CASE
其中的EJB3NamingStrategy
只是使用表名不变。
If you don't want to change the naming strategy you could always just specify your column name in lowercase:
如果您不想更改命名策略,您可以始终以小写形式指定列名:
@Column(name="testname")
回答by ncaralicea
It seems that
看起来
@Column(name="..")
@Column(name="..")
is completely ignored unless there is
完全忽略,除非有
spring.jpa.hibernate.naming_strategy=org.hibernate.cfg.EJB3NamingStrategy
spring.jpa.hibernate.naming_strategy=org.hibernate.cfg.EJB3NamingStrategy
specified, so to me this is a bug.
指定,所以对我来说这是一个错误。
I spent a few hours trying to figure out why @Column(name="..") was ignored.
我花了几个小时试图弄清楚为什么 @Column(name="..") 被忽略了。
回答by Romeo Jr Maranan
teteArg, thank you so much. Just an added information so, everyone bumping into this question will be able to understand why.
teteArg,非常感谢。只是一个附加的信息,所以每个碰到这个问题的人都能理解为什么。
What teteArgsaid is indicated on the Spring Boot Common Properties: http://docs.spring.io/spring-boot/docs/current/reference/html/common-application-properties.html
什么teteArg说,在春季启动通用属性表示:http://docs.spring.io/spring-boot/docs/current/reference/html/common-application-properties.html
Apparently, spring.jpa.hibernate.naming.strategyis not a supported property for Spring JPA implementation using Hibernate 5.
显然,spring.jpa.hibernate.naming.strategy不是使用 Hibernate 5 的 Spring JPA 实现支持的属性。
回答by Sanjiv Jivan
The only solution that worked for me was the one posted by teteArg above. I'm on Spring Boot 1.4.2 w/Hibernate 5. Namely
唯一对我有用的解决方案是上面 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
For additional insight I'm posting the call trace so that its clear what calls Spring is making into Hibernate to setup the naming strategy.
为了获得更多见解,我发布了调用跟踪,以便清楚 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.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.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)
回答by Orhan
The default strategy for @Column(name="TestName")
will be test_name
, this is correct behavior!
@Column(name="TestName")
will的默认策略是test_name
,这是正确的行为!
If you have a column named TestName
in your database you should change Column annotation to @Column(name="testname")
.
如果您TestName
的数据库中有一个名为的列,则应将 Column 注释更改为@Column(name="testname")
.
This works because database does not care if you name your column TestName or testname (column names are case insensitive!!).
这是有效的,因为数据库不关心您是将列命名为TestName 还是 testname (列名不区分大小写!!)。
But beware, the same does not apply for database name and table names, that are case sensitive on Unix systems but case in sensitive on Windows systems (the fact that probably kept a lot of people awake at night, working on windows but deploying on linux :))
但请注意,这同样不适用于数据库名称和表名称,它们在 Unix 系统上区分大小写,但在 Windows 系统上区分大小写(这一事实可能让很多人彻夜难眠,在 Windows 上工作但在 linux 上部署:))
回答by Dean
If you want to use @Column(...), then use small-case letters always even though your actual DB column is in camel-case.
如果你想使用@Column(...),那么即使你的实际数据库列是驼峰式的,也总是使用小写字母。
Example: If your actual DB column name is TestName
then use:
示例:如果您的实际数据库列名称是TestName
然后使用:
@Column(name="testname") //all small-case
If you don't like that, then simply change the actual DB column name into: test_name
如果您不喜欢那样,那么只需将实际的数据库列名称更改为:test_name
回答by java-addict301
In my case, the annotation was on the getter() method instead of the field itself (ported from a legacy application).
就我而言,注释位于 getter() 方法上,而不是字段本身(从遗留应用程序移植而来)。
Spring ignores the annotation in this case as well but doesn't complain. The solution was to move it to the field instead of the getter.
在这种情况下,Spring 也会忽略注释,但不会抱怨。解决方案是将其移动到现场而不是吸气剂。
回答by Mohammad Cali
Turns out that I just have to convert @column
name testName to all small letters, since it was initially in camel case.
原来我只需要将@column
名称 testName转换为所有小写字母,因为它最初是驼峰式的。
Although I was not able to use the official answer, the question was able to help me solve my problem by letting me know what to investigate.
虽然我无法使用官方答案,但该问题通过让我知道要调查的内容来帮助我解决问题。
Change:
改变:
@Column(name="testName")
private String testName;
To:
到:
@Column(name="testname")
private String testName;