कैसे JPA एनोटेशन के साथ MYSQL स्वनिर्धारण क्षेत्र एनोटेट करने के लिए


106

सीधे मुद्दे पर, समस्या ऑब्जेक्ट ऑपरेटर को MySQL DB में सहेज रही है। बचाने से पहले, मैं इस तालिका से चयन करने का प्रयास करता हूं और यह काम करता है, इसलिए db से कनेक्शन है।

यहाँ मेरी संचालक वस्तु है:

@Entity
public class Operator{

   @Id
   @GeneratedValue
   private Long id;

   private String username;

   private String password;


   private Integer active;

   //Getters and setters...
}

बचाने के लिए मैं JPA EntityManagerकी persistविधि का उपयोग करता हूं ।

यहाँ कुछ लॉग है:

Hibernate: insert into Operator (active, password, username, id) values (?, ?, ?, ?)
com.mysql.jdbc.JDBC4PreparedStatement@15724a0: insert into Operator (active,password, username, id) values (0, 'pass', 'user', ** NOT SPECIFIED **)

जिस तरह से मैं इसे देखता हूं, समस्या ऑटो वेतन वृद्धि के साथ कॉन्फ़िगरेशन है, लेकिन मैं यह पता नहीं लगा सकता हूं कि कहां है।

कुछ चालें मैंने यहाँ देखी हैं: हाइबरनेट MySQL auto_increment प्राथमिक कुंजी फ़ील्ड का सम्मान नहीं कर रहा है, लेकिन इसमें से कुछ भी काम नहीं किया है

अगर किसी अन्य विन्यास फाइल की जरूरत है तो मैं उन्हें प्रदान करूंगा।

DDL:

CREATE TABLE `operator` ( 
`id` INT(10) NOT NULL AUTO_INCREMENT,
`first_name` VARCHAR(40) NOT NULL,
`last_name` VARCHAR(40) NOT NULL,
`username` VARCHAR(50) NOT NULL,
`password` VARCHAR(50) NOT NULL,
`active` INT(1) NOT NULL,
PRIMARY KEY (`id`)
)

आप हाइबरनेट के किस संस्करण का उपयोग कर रहे हैं?
स्टीवन बेनिटेज़

जवाबों:


150

MySQL AUTO_INCREMENTकॉलम का उपयोग करने के लिए , आपको एक IDENTITYरणनीति का उपयोग करना चाहिए :

@Id @GeneratedValue(strategy=GenerationType.IDENTITY)
private Long id;

AUTOMySQL के साथ उपयोग करने पर आपको क्या मिलेगा :

@Id @GeneratedValue(strategy=GenerationType.AUTO)
private Long id;

जो वास्तव में इसके बराबर है

@Id @GeneratedValue
private Long id;

दूसरे शब्दों में, आपके मानचित्रण को काम करना चाहिए। लेकिन हाइबरनेट को idएसक्यूएल इंसर्ट स्टेटमेंट में कॉलम को छोड़ देना चाहिए , और यह नहीं है। कहीं न कहीं एक तरह का बेमेल होना चाहिए।

क्या आपने अपने हाइबरनेट कॉन्फ़िगरेशन में एक MySQL बोली निर्दिष्ट की है (शायद MySQL5InnoDBDialectया MySQL5Dialectआपके द्वारा उपयोग किए जा रहे इंजन के आधार पर)?

इसके अलावा, तालिका किसने बनाई? क्या आप संबंधित DDL दिखा सकते हैं?

अनुवर्ती: मैं आपकी समस्या को पुन : पेश नहीं कर सकता। अपनी इकाई और अपने DDL के कोड का उपयोग करते हुए , हाइबरनेट MySQL के साथ निम्नलिखित (अपेक्षित) SQL उत्पन्न करता है:

insert 
into
    Operator
    (active, password, username) 
values
    (?, ?, ?)

ध्यान दें कि idकॉलम उपरोक्त कथन से अनुपस्थित है, जैसा कि अपेक्षित है।

योग करने के लिए, आपके कोड, तालिका की परिभाषा और बोली सही और सुसंगत हैं, यह काम करना चाहिए। यदि यह आपके लिए नहीं है, तो शायद कुछ सिंक से बाहर है (एक साफ निर्माण करें, बिल्ड डायरेक्टरी की दोहरी जांच करें, आदि) या कुछ और गलत है (कुछ भी संदिग्ध के लिए लॉग की जांच करें)।

बोली के बारे में, या केवल इतना ही अंतर है कि बाद में डीडीएल बनाते समय तालिका ऑब्जेक्ट में जोड़ा जाता है। एक या दूसरे का उपयोग करने से उत्पन्न SQL नहीं बदलता है।MySQL5DialectMySQL5InnoDBDialectENGINE=InnoDB


पास्कल, आप इसके बारे में सही हैं, लेकिन मेरी कॉन्फिग फाइलों में कुछ ठीक नहीं है। हो सकता है कि कोई भी अन्य शर्करा, अब मैंने नई जानकारी और फ़ाइलों को कॉन्फ़िगर किया है?
trivunm

9
@Pascal - मैंने पाया कि मैं जरूरत @GeneratedValue (रणनीति = GenerationType.IDENTITY) जेपीए 2 का उपयोग कर जब ठीक से काम करने के लिए AUTO_INCREMENT पाने के लिए / हाइबरनेट 4.0.0.CR2 / JBoss के रूप में 7. bit.ly/tdNyOJ
यहोशू डेविस

4
ध्यान दें कि MySQL के लिए सही है । PostgreSQL के साथ @GeneratedValue(strategy=GenerationType.IDENTITY)जब आप लिखते हैं @GeneratedValue(strategy=GenerationType.AUTO)और आपको नहीं मिलता है @GeneratedValue। इसलिए सावधान रहें और क्रिया करने की कोशिश करें।
सज्जादानगर

ध्यान दें: हाइबरनेट और / या MySQL / MariaDB GenerationType.AUTO के हाल के संस्करणों के साथ GenerationType.TABLE के लिए डिफ़ॉल्ट होगा। जो अपग्रेड करते समय सिंक अनुक्रमों के साथ खराब समस्याओं को जन्म दे सकता है।
jwenting 10

तालिका को फिर से बनाना मत भूलना: spring.jpa.hibernate.ddl-auto = create। अपडेट के साथ यह काम नहीं करेगा
ग्लासनहोस्ट

38

MySQL का उपयोग करते हुए, केवल यही दृष्टिकोण मेरे लिए काम कर रहा था:

@Id @GeneratedValue(strategy=GenerationType.IDENTITY)
private Long id;

पास्कल द्वारा उनके उत्तर में बताए गए अन्य 2 दृष्टिकोण मेरे लिए काम नहीं कर रहे थे।


हाँ, मैंने अपने प्रश्न / उत्तर में इसका खंडन किया। stackoverflow.com/questions/39675714/…
यान खोंस्की

धन्यवाद, यह मेरे लिए काम करते हैं, मैं उपयोग कर रहा हूँ JPAके साथ spring-boot और MySQL
ओसामा अल-बन्ना

12

यह पढ़ने वाले किसी के लिए जो JPA 2.0 के लिए EclipseLink का उपयोग कर रहा है, यहां दो एनोटेशन हैं, जिनका उपयोग मुझे डेटा को बनाए रखने के लिए JPA प्राप्त करने के लिए करना था, जहां "MySequenceGenerator" जो भी नाम आप जनरेटर को देना चाहते हैं, "myschema" का नाम है आपके डेटाबेस में स्कीमा जिसमें अनुक्रम ऑब्जेक्ट शामिल है, और डेटाबेस में अनुक्रम ऑब्जेक्ट का नाम "myfterence" है।

@GeneratedValue(strategy= GenerationType.SEQUENCE, generator="MySequenceGenerator")
@SequenceGenerator(allocationSize=1, schema="myschema",  name="MySequenceGenerator", sequenceName = "mysequence")

EclipseLink (और संभवतः अन्य JPA प्रदाताओं) का उपयोग करने वालों के लिए, यह महत्वपूर्ण है कि आप डेटाबेस में अपने अनुक्रम के लिए परिभाषित INCREMENT मूल्य से मिलान करने के लिए आवंटन विशेषता सेट करें। यदि आप नहीं करते हैं, तो आप एक सामान्य दृढ़ता विफलता प्राप्त करेंगे, और इसे ट्रैक करने की कोशिश कर रहे समय का एक अच्छा सौदा बर्बाद करते हैं, जैसे मैंने किया। यहाँ संदर्भ पृष्ठ है जो मुझे इस चुनौती से उबरने में मदद करता है:

http://wiki.eclipse.org/EclipseLink/Examples/JPA/PrimaryKey#Using_Sequence_Objects

इसके अलावा, संदर्भ देने के लिए, यहां हम उपयोग कर रहे हैं:

जावा 7 ग्लासफिश 3.1 पोस्टग्रेक्यूएल 9.1 प्राइमफेस 3.2 / जेएसएफ 2.1

इसके अलावा, आलसीपन के लिए, मैंने इसे नेटबीन्स में डीबी से एंटिटी बनाने के लिए विजिटर के साथ बनाया, एंटिटीज से कंट्रोलर और एंटिटीज से जेएसएफ, और विजार्ड्स (जाहिर तौर पर) को पता नहीं है कि सीक्वेंस बेस्ड आईडी कॉलम कैसे डील करते हैं, इसलिए आपको इन टिप्पणियों को मैन्युअल रूप से जोड़ना होगा।


6

कृपया सुनिश्चित करें कि आईडी डेटाटाइप स्ट्रिंग के बजाय लंबा है, अगर वह स्ट्रिंग होगा तो @GeneratedValue एनोटेशन काम नहीं करेगा और इसके लिए sql जनरेटिंग

@Id @GeneratedValue(strategy=GenerationType.IDENTITY)
private String id;

create table VMS_AUDIT_RECORDS (id **varchar(255)** not null auto_increment primary key (id))

होना चाहिए

create table VMS_AUDIT_RECORDS (id **bigint** not null auto_increment primary key (id))

6

यदि आप हाइबरनेट v3 के साथ मैसकल का उपयोग कर रहे हैं, तो इसका उपयोग करना ठीक है GenerationType.AUTOक्योंकि आंतरिक रूप से यह उपयोग करेगा GenerationType.IDENTITY, जो MySQL के लिए सबसे इष्टतम है।

हालाँकि Hibernate v5 में, यह बदल गया है। GenerationType.AUTOउपयोग करेगा GenerationType.TABLEजो प्रविष्टि के लिए बहुत अधिक प्रश्न उत्पन्न करता है।

आप इसका उपयोग करने से बच सकते हैं GenerationType.IDENTITY(यदि MySQL एकमात्र डेटाबेस है जिसका आप उपयोग कर रहे हैं) या इन नोटेशन के साथ (यदि आपके पास कई डेटाबेस हैं):

@GeneratedValue(strategy = GenerationType.AUTO, generator = "native")
@GenericGenerator(name = "native", strategy = "native")

हां, अपने स्प्रिंग एप्लिकेशन को अपग्रेड करते समय कुछ बुरा रिग्रेशन त्रुटियों के लिए मुश्किल कारण जो कि हाइबरनेट को भी अपग्रेड करता है।
jwenting

1

मैंने हर चीज़ की कोशिश की, लेकिन फिर भी मैं ऐसा नहीं कर पाया, मैं mysql का उपयोग कर रहा हूं, हाइबरनेट के साथ jpa, मैंने अपने इश्यू को कंस्ट्रक्टर में id 0 के मान से हल किया है और बाद में मेरा आईडी डिक्लेरेशन कोड है

@Id
@Column(name="id",updatable=false,nullable=false)
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

1

जैसा कि आपने डेटाबेस निर्माण में आईडी को int प्रकार में परिभाषित किया है, आपको मॉडल वर्ग में भी उसी डेटा प्रकार का उपयोग करना होगा। और जैसा कि आपने डेटाबेस में आईडी को ऑटो वृद्धि के लिए परिभाषित किया है, आपको एनोटेशन @GeneratedValue के भीतर विशेषता 'रणनीति' में मान 'GenerationType.AUTO' पास करके मॉडल वर्ग में इसका उल्लेख करना होगा। फिर नीचे जैसा कोड बन जाता है।

@Entity
public class Operator{

  @Id
  @GeneratedValue(strategy = GenerationType.AUTO)
  private int id;

  private String username;

  private String password;

  private Integer active;

  //Getters and setters...
}

1

पास्कल के रूप में ही जवाब दिया, बस अगर आप का उपयोग करने की जरूरत है। किसी कारण के लिए आप बस अपने आवेदन गुणों में जोड़ने की जरूरत है:

spring.jpa.show-sql=true
spring.jpa.properties.hibernate.format_sql=true
spring.jpa.hibernate.ddl-auto = update

0

क्या आप जाँच सकते हैं कि आप सही डेटाबेस से जुड़े हैं या नहीं। जैसा कि मैंने एक ही मुद्दे का सामना किया था, लेकिन आखिरकार मैंने पाया कि मैं अलग-अलग डेटाबेस से जुड़ा हुआ हूं।

पहचान DB2, MySQL, MS SQL सर्वर, Sybase और HypersonicSQL में पहचान कॉलम का समर्थन करता है। लौटाया गया पहचानकर्ता प्रकार लंबा, छोटा या इंट का है।

अधिक जानकारी: http://docs.jboss.org/hibernate/orm/3.5/reference/en/html/mapping.html#mapping-declaration-id


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