Spring Boot + JPA: имя столбца аннотация игнорируется
у меня есть приложение Spring Boot с зависимостью spring-boot-starter-data-jpa. Мой класс сущностей имеет аннотацию столбца с именем столбца. Например:
@Column(name="TestName")
private String testName;
SQL генерируется этим created test_name как имя столбцов. После поиска решения я нашел, что spring.jpa.hibernate.naming_strategy=org.hibernate.cfg.EJB3NamingStrategy решена проблема (имя столбца берется из аннотации столбца).
тем не менее, мой вопрос в том, почему без 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
8 ответов:
для hibernate5 я решил эту проблему, поставив следующие строки в моем приложении.файл свойств:
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атрибут или если он был неявно сгенерирован из имени Поля.The
ImprovedNamingStrategyпреобразуетCamelCaseдоSNAKE_CASEгдеEJB3NamingStrategyпросто использует имя таблицы без изменений.если вы не хотите менять стратегию именования, вы можете всегда просто укажите имя столбца в нижнем регистре:
@Column(name="testname")
кажется,
@Column(name="..")
полностью игнорируется, если нет
весна.СПД.зимовать.naming_strategy=org.зимовать.контекстно-свободная грамматика.EJB3NamingStrategy
указано, так что для меня это баг.
Я потратил несколько часов, пытаясь выяснить, почему @Column (name="..") был проигнорирован.
единственное решение, которое сработало для меня, было опубликовано 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 делает в спящий режим, чтобы настроить стратегию именования.
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)
teteArg, большое вам спасибо. Просто добавленная информация так, каждый натыкаясь на этот вопрос сможет понять, почему.
Что teteArg said указывается на общих свойствах Spring Boot: http://docs.spring.io/spring-boot/docs/current/reference/html/common-application-properties.html
видимо, весна.СПД.зимовать.называющий.стратегия не является поддерживаемым свойством для Spring JPA реализация с помощью 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имея только одну строку, предложенную ncaralicea не работает для меня
стратегия по умолчанию для
@Column(name="TestName")будетtest_name, это правильное поведение!если у вас есть столбец с именем
TestNameв вашей базе данных, вы должны изменить аннотации столбце@Column(name="testname").это работает, потому что база данных не заботится, если вы называете свой столбец TestName или testname (имена столбцов нечувствительны к регистру!!).
но будьте осторожны, то же самое не относится к имени базы данных и именам таблиц, которые чувствительны к регистру в системах Unix но дело в чувствительных системах Windows (тот факт, что, вероятно, многие люди не спали ночью, работая на windows, но развертывая на linux :))
Если вы хотите использовать @Column(...), затем всегда используйте прописные буквы, даже если ваш фактический столбец DB находится в camel-case.
пример: если ваше фактическое имя столбца БД: TestName затем используйте:
@Colunm(name="testname") //all small-caseЕсли вам это не нравится, то просто измените фактическое имя столбца БД на: имя_проверки
Comments