[java] Spring Boot + JPA : 열 이름 주석 무시

종속성이있는 Spring Boot 애플리케이션이 spring-boot-starter-data-jpa있습니다. 내 항목 클래스에는 열 이름이있는 열 주석이 있습니다. 예를 들면 :

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

이에 의해 생성 된 SQL test_name은 열 이름으로 생성됩니다 . 해결책을 찾은 spring.jpa.hibernate.naming_strategy=org.hibernate.cfg.EJB3NamingStrategy후 문제 가 해결 되었음을 발견했습니다 (열 이름은 열 주석에서 가져옴).

그래도 내 질문은 왜 naming_strategy를 EJB3NamingStrategyJPA로 설정하지 않으면 열 주석을 무시하는 것입니까? 어쩌면 동면 방언이 그것과 관련이 있습니까? MS SQL 2014 Express에 연결 중이며 로그에 다음이 포함됩니다.

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



답변

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


답변

기본적으로 Spring은 org.springframework.boot.orm.jpa.SpringNamingStrategy테이블 이름을 생성하는 데 사용 합니다. 이것은의 매우 얇은 확장입니다 org.hibernate.cfg.ImprovedNamingStrategy. tableName해당 클래스 의 메서드에는 소스 String값 이 전달 되지만 @Column.name속성 에서 가져온 것인지 필드 이름에서 암시 적으로 생성되었는지 는 인식하지 못합니다 .

는 변경되지 않은 테이블 이름을 사용하는 곳으로 ImprovedNamingStrategy변환 CamelCase됩니다 .SNAKE_CASEEJB3NamingStrategy

이름 지정 전략을 변경하지 않으려면 항상 열 이름을 소문자로 지정할 수 있습니다.

@Column(name="testname")


답변

그것은 보인다

@ 열 (name = “..”)

없는 한 완전히 무시됩니다

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

나에게 이것은 버그입니다.

@Column (name = “..”)이 무시 된 이유를 알아 내려고 몇 시간을 보냈습니다.


답변

의 기본 전략은 @Column(name="TestName")입니다 test_name. 이것은 올바른 동작입니다!

TestName데이터베이스에 이름이 지정된 열이있는 경우 열 주석을로 변경해야합니다 @Column(name="testname").

이것은 데이터베이스가 열 이름을 TestName 또는 testname ( 열 이름은 대소 문자를 구분하지 않습니다 !! )로 지정해도 상관하지 않기 때문에 작동합니다 .

그러나 유닉스 시스템에서는 대소 문자를 구분하지만 Windows 시스템에서는 대소 문자를 구분하는 데이터베이스 이름과 테이블 이름에는 동일하게 적용되지 않습니다 (아마도 많은 사람들이 밤에 깨어 있고 Windows에서 작업하지만 Linux에서 배포하는 사실은 :))


답변

나를 위해 일한 유일한 솔루션은 위의 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)


답변

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 구현을 위해 지원되는 속성이 아닙니다.


답변

내가 변환해야한다는 것이 밝혀졌습니다. @column처음에는 카멜 케이스 였기 때문에 testName이라는 이름을 모두 소문자 하면됩니다.

공식 답변을 사용할 수는 없었지만 조사해야 할 사항을 알려줌으로써 문제를 해결하는 데 도움이 될 수있었습니다.

변화:

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

에:

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