स्प्रिंग बूट + जेपीए: कॉलम नाम एनोटेशन की अनदेखी की गई


121

मेरे पास निर्भरता के साथ एक स्प्रिंग बूट एप्लिकेशन है spring-boot-starter-data-jpa। मेरी इकाई कक्षा में एक स्तंभ नाम के साथ एक कॉलम एनोटेशन है। उदाहरण के लिए:

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

इससे उत्पन्न SQL test_nameस्तंभ नाम के रूप में बनाया गया है। एक समाधान की तलाश के बाद मैंने पाया है कि spring.jpa.hibernate.naming_strategy=org.hibernate.cfg.EJB3NamingStrategyसमस्या का समाधान (स्तंभ का नाम स्तंभ एनोटेशन से लिया गया है)।

फिर भी, मेरा सवाल यह है कि EJB3NamingStrategyजेपीए के नामकरण के बिना कॉलम एनोटेशन की अनदेखी क्यों की जा रही है? शायद हाइबरनेट बोली का इससे कोई लेना-देना है? मैं एमएस एसक्यूएल 2014 एक्सप्रेस से जुड़ रहा हूं और मेरे लॉग में शामिल हैं:

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

1
यह प्रश्न स्पष्ट रूप से प्रदान किए गए स्तंभ नाम के बारे में है जिसे अनदेखा करने के बजाय बदल दिया गया है । यह करने पर निर्भर करता यह किया जा रहा है की उम्मीद के बजाय मार डाला पारदर्शी संस्करण । हाइबरनेट वास्तव में @Column(name="...")एनोटेशन की उपेक्षा कर सकता है , उदाहरण के लिए जब आप अपेक्षित पहुंच प्रकार के अलावा अन्य का उपयोग करते हैं, लेकिन यहां ऐसा नहीं है।
वेस्टीमिल ओवकास

जवाबों:


163

हाइबरनेट 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

30
spring.jpa.hibernate.naming.physical-strategy = org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl, केवल इस संपत्ति को नाम रखने के लिए आवश्यक है।
अभिषेक रिंगिया 19

1
मेरे पास एक ही मुद्दा था और उन 2 गुणों को जोड़कर मेरे लिए इसे हल किया। मैं स्प्रिंग बूट 1.4.3
जोहान

1
यह एकमात्र समाधान है जो मेरे लिए भी काम करता है। मैं स्प्रिंग बूट 1.4.2 का उपयोग कर रहा हूं
संजीव जीवन

मैं स्प्रिंग बूट 1.5.9 का उपयोग कर रहा हूं। कृपया, यह पोस्ट मेरे लिए काम करता है
IcyBrk

बहुत बढ़िया .. मैं सोच रहा था कि यह मेरे @ कॉलम के एनोटेशन की अनदेखी क्यों कर रहा था। अंत में इससे मुझे मदद मिली। मेरे लिए, मुझे लगता है कि यह एक बग या लापता कार्यक्षमता है।
राजू पेनुमात्सा

86

डिफ़ॉल्ट रूप से स्प्रिंग org.springframework.boot.orm.jpa.SpringNamingStrategyतालिका नाम उत्पन्न करने के लिए उपयोग करता है। यह का बहुत पतला विस्तार है org.hibernate.cfg.ImprovedNamingStrategytableNameकि कक्षा में विधि एक स्रोत पारित हो जाता है Stringमूल्य, लेकिन यह अनजान अगर यह एक से आता है @Column.nameविशेषता या यह परोक्ष फ़ील्ड नाम से तैयार की गई है, तो।

ImprovedNamingStrategyपरिवर्तित कर देंगे CamelCaseकरने के लिए SNAKE_CASEजहां के रूप में EJB3NamingStrategyसिर्फ तालिका नाम अपरिवर्तित उपयोग करता है।

यदि आप नामकरण की रणनीति को बदलना नहीं चाहते हैं तो आप हमेशा अपने कॉलम का नाम लोअरकेस में निर्दिष्ट कर सकते हैं:

@Column(name="testname")

1
हाय, फिल। स्प्रिंग बूट का उपयोग करके, मैंने स्प्रिंग.jpa.hibernate.naming.strategy: org.hibernate.cfg.EJB3NamingStrategy जोड़ दिया है। लेकिन ऐसा लगता है कि मेरे लिए काम नहीं है। क्या आप मेरी मदद कर सकते हैं?
10

प्रतिक्रिया का महत्वपूर्ण हिस्सा निचले मामले में नाम रखना है! मैं सलाह देता हूं कि स्टैजि को न बदलें लेकिन नाम रखना कम है क्योंकि कॉलम नाम केस असंवेदनशील है!
loicmathieu

31

ऐसा लगता है

@Column (नाम = "..")

जब तक पूरी तरह से नजरअंदाज नहीं किया जाता है

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

निर्दिष्ट, तो मेरे लिए यह एक बग है।

मैंने यह जानने में कुछ घंटे बिताए कि क्यों @ कॉलम (नाम = "..") को अनदेखा किया गया।


4
मुझे भी यही समस्या थी। मैंने यहां एक समस्या रिपोर्ट जोड़ी: github.com/spring-projects/spring-boot/issues/2129
Kacper86

बहुत बहुत धन्यवाद। मेरे एप्लिकेशन को मौजूदा डीबी पर इंगित करने के लिए एक दिन के बारे में खोया।
दिमित्री इरोखिन

यह वास्तव में नजरअंदाज नहीं किया जाता है, बस दिए गए नाम विशेषता पर डिफ़ॉल्ट वसंत नामकरण की रणनीति लागू की जाती है। @PhilWebb उत्तर पढ़ें
मिशेल

15

के लिए डिफ़ॉल्ट रणनीति @Column(name="TestName")होगी test_name, यह सही व्यवहार है!

यदि TestNameआपके डेटाबेस में एक कॉलम है, तो आपको कॉलम एनोटेशन को बदलना चाहिए @Column(name="testname")

यह काम करता है क्योंकि डेटाबेस को परवाह नहीं है यदि आप अपने कॉलम का नाम TestName या testname ( स्तंभ नाम केस असंवेदनशील हैं )।

लेकिन सावधान रहें, डेटाबेस के नाम और टेबल के नामों के लिए भी यह लागू नहीं होता है, जो यूनिक्स सिस्टम पर संवेदनशील होते हैं, लेकिन विंडोज सिस्टम पर संवेदनशील होने के मामले में (यह तथ्य कि शायद बहुत सारे लोग रात में जागते हैं, खिड़कियों पर काम करते हैं लेकिन लिनक्स पर तैनात होते हैं। :))


3
1. वास्तव में यह सच नहीं है, आपके द्वारा उपयोग किए जा रहे डेटाबेस के कॉन्फ़िगरेशन के आधार पर कॉलम नाम संवेदनशील हो सकते हैं ... 2. @ कॉलम नाम - जैसा कि नाम से पता चलता है कि डेटाबेस स्तंभ नाम प्रदान करने के लिए एक जगह होनी चाहिए, न कि कुछ पहचानकर्ता जो एक रूपरेखा है। रनटाइम के दौरान बदल जाएगा ..
कामिल

1. धन्यवाद, क्या आप db का उदाहरण दे सकते हैं जहाँ कॉलम नाम डिफ़ॉल्ट रूप से संवेदनशील हैं? 2. वास्तव में @ कॉलेयम हमें तार्किक नाम देता है जो PhysicalNamingStrategy द्वारा भौतिक नामों से हल किया जाता है, कम से कम ऐसा प्रतीत होता है कि डॉक्टर क्या कहता है: docs.jboss.org/hibernate/orm/5.1/usnguide/html_single/chapters/…
Orhan

2
1.Sorry मैं नहीं कर सकता क्योंकि मुझे परवाह नहीं है कि यह डिफ़ॉल्ट रूप से किसके पास है, मुझे परवाह है कि जो मैं उपयोग कर रहा हूं उस पर DBA द्वारा कौन सी सेटिंग्स सेट की गई हैं। 2. यह दुर्भाग्य से सच है - यह सिर्फ मेरी व्यक्तिगत राय है कि यह दृष्टिकोण गलत है क्योंकि यह मुझे सोचने पर मजबूर करता है या अंत में कॉलम को नाम कैसे दिया जाएगा, या कौन सी नामकरण रणनीति का उपयोग करना है जो प्रदान किए गए नामों को नहीं छूता है।
कामिल

1
सच है, यह सबसे सहज समाधान होगा, और निश्चित रूप से इस पर बेहतर प्रलेखन चोट नहीं पहुंचाएगा।
ओरहान

स्पष्ट रूप से सेट किए गए कॉलम का नाम सभी शर्तों के तहत होना चाहिए, जो एक अनुमानित रूप से उत्पन्न होता है। यदि ऐसा नहीं होता है, तो जेपीए कार्यान्वयन में एक बग है।
13

13

एकमात्र समाधान जो मेरे लिए काम करता था वह था teteArg द्वारा पोस्ट किया गया। मैं स्प्रिंग बूट पर हूँ 1.4.2 w / हाइबरनेट 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

अतिरिक्त जानकारी के लिए मैं कॉल ट्रेस पोस्ट कर रहा हूं ताकि इसका स्पष्ट नाम स्प्रिंग कॉलिंग हाइबरनेट में नामकरण रणनीति को सेट कर सके।

      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)

6

teteArg , बहुत बहुत धन्यवाद। बस एक अतिरिक्त जानकारी, इस सवाल से टकराते हुए हर कोई समझ सकता है कि क्यों।

क्या कहा जाता है teteArg स्प्रिंग बूट कॉमन प्रॉपर्टीज पर इंगित किया गया है: http://docs.spring.io/spring-boot/docs/current/reference/html/common-application-properties.html

जाहिर है, spring.jpa.hibernate.naming.strategy हाइबरनेट 5 का उपयोग कर स्प्रिंग जेपीए कार्यान्वयन के लिए एक समर्थित संपत्ति नहीं है।


आप मदद करने के लिए खुश हूँ
teteArg

4

यह @columnबताता है कि मुझे सिर्फ नाम के नाम को सभी छोटे अक्षरों में बदलना है, क्योंकि यह शुरू में ऊंट के मामले में था।

हालाँकि मैं आधिकारिक उत्तर का उपयोग करने में सक्षम नहीं था, लेकिन सवाल यह था कि मुझे अपनी समस्या को हल करने में मेरी मदद करने में सक्षम था जो मुझे पता था कि क्या जांच करनी है।

परिवर्तन:

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

सेवा:

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

3

यदि आप @ कॉलम (...) का उपयोग करना चाहते हैं, तो हमेशा छोटे केस वाले अक्षरों का उपयोग करें, भले ही आपका वास्तविक DB कॉलम ऊंट-केस में हो।

उदाहरण: यदि आपका वास्तविक DB कॉलम नाम है TestNameतो उपयोग करें:

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

यदि आपको वह पसंद नहीं है, तो बस वास्तविक DB कॉलम नाम को बदल दें: test_name


1

मेरे मामले में, एनोटेशन क्षेत्र के बजाय गेट्टर () विधि पर था (एक विरासत अनुप्रयोग से पोर्ट किया गया)।

वसंत इस मामले में भी एनोटेशन की अनदेखी करता है लेकिन शिकायत नहीं करता है। समाधान यह था कि इसे गेट्टर की जगह मैदान में ले जाया जाए।


1
अद्यतन के लिए धन्यवाद। वास्तव में मूल्यवान जानकारी।
13
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.