java - physical - spring jpa hibernate naming strategy org hibernate cfg improvednamingstrategy
Spring Boot+JPA: anotaciĆ³n de nombre de columna ignorada (8)
Tengo una aplicación Spring Boot con la dependencia "spring-boot-starter-data-jpa". Mi clase de entidad tiene una anotación de columna con el nombre de la columna. Por ejemplo:
@Column(name="TestName")
private String testName;
SQL generado por este test_name creado como nombre de columna. Después de buscar la solución, he encontrado que spring.jpa.hibernate.naming_strategy=org.hibernate.cfg.EJB3NamingStrategy
resolvió el problema (el nombre de la columna se toma de la anotación de la columna).
Aún así, mi pregunta es ¿por qué sin naming_strategy establecido en EJB3NamingStrategy
JPA está ignorando la anotación de columna? ¿Quizás el dialecto Hibernate tiene algo que ver con eso? Me estoy conectando a MS SQL 2014 Express y mis registros contienen:
Unknown Microsoft SQL Server major version [12] using SQL Server 2000 dialect
Using dialect: org.hibernate.dialect.SQLServerDialect
, muchas gracias. Solo una información adicional, de modo que cualquiera que se tope con esta pregunta podrá entender por qué.
Lo que dijo está indicado en las propiedades comunes de Spring Boot: http://docs.spring.io/spring-boot/docs/current/reference/html/common-application-properties.html
Aparentemente, spring.jpa.hibernate.naming.strategy no es una propiedad compatible para la implementación Spring JPA utilizando Hibernate 5.
De forma predeterminada, Spring utiliza org.springframework.boot.orm.jpa.SpringNamingStrategy
para generar nombres de tablas. Esta es una extensión muy delgada de org.hibernate.cfg.ImprovedNamingStrategy
. El método tableName
en esa clase se pasa un valor de String
origen pero no se sabe si proviene de un atributo @Column.name
o si se ha generado implícitamente a partir del nombre del campo.
The ImprovedNamingStrategy
convertirá CamelCase
en SNAKE_CASE
donde, como EJB3NamingStrategy
solo utiliza el nombre de la tabla sin cambios.
Si no desea cambiar la estrategia de nombres, siempre puede especificar su nombre de columna en minúsculas:
@Column(name="testname")
La única solución que funcionó para mí fue la publicada por teteArg arriba. Estoy en Spring Boot 1.4.2 w / Hibernate 5. A saber
spring.jpa.hibernate.naming.implicit-strategy=org.hibernate.boot.model.naming.ImplicitNamingStrategyLegacyJpaImpl
spring.jpa.hibernate.naming.physical-strategy=org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
Para obtener información adicional, estoy publicando el seguimiento de llamadas para que quede claro qué llamadas hace Spring a Hibernate para configurar la estrategia de nombres.
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)
La estrategia predeterminada para @Column(name="TestName")
será test_name
, ¡este es el comportamiento correcto!
Si tiene una columna llamada TestName
en su base de datos, debe cambiar la anotación de Columna a @Column(name="testname")
.
Esto funciona porque a la base de datos no le importa si nombra su columna TestName o testname (los nombres de las columnas no distinguen entre mayúsculas y minúsculas ).
Pero cuidado, lo mismo no se aplica al nombre de la base de datos y los nombres de las tablas, que distinguen entre mayúsculas y minúsculas en los sistemas Unix pero que son sensibles en los sistemas Windows (el hecho de que probablemente mantiene a muchas personas despiertas por la noche, trabajando en Windows pero implementando en Linux :))
Lo único que funcionó para mí fue tener ambas líneas de código publicadas anteriormente:
spring.jpa.hibernate.naming.implicit-strategy=org.hibernate.boot.model.naming.ImplicitNamingStrategyLegacyJpaImpl
spring.jpa.hibernate.naming.physical-strategy=org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
Tener solo la línea propuesta por ncaralicea no funcionó para mí
Para hibernate5 resolví este problema al poner las siguientes líneas en mi archivo 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
Parece que
@Column (name = "..")
es completamente ignorado a menos que haya
spring.jpa.hibernate.naming_strategy = org.hibernate.cfg.EJB3NamingStrategy
especificado, entonces para mí esto es un error.
Pasé unas horas tratando de descubrir por qué @Column (name = "..") fue ignorado.
Si desea utilizar @Column (...), utilice letras minúsculas siempre aunque su columna DB real esté en camel-case.
Ejemplo: si su nombre de columna DB real es: TestName, utilice:
@Colunm(name="testname") //all small-case
Si no te gusta, simplemente cambia el nombre de la columna DB actual a: test_name