2017-08-29 11 views
5

मैं है कोड के निम्नलिखित लाइनों:(Iterable <S> संस्थाओं) कितनी बार डाटाबेस स्प्रिंग आंकड़े जेपीए के बचाने में मारा जाता है

@Transactional 
public interface UserRepository extends UserBaseRepository<User> { 
} 

@NoRepositoryBean 
public interface UserBaseRepository<T extends User> extends CrudRepository<T, Long> { 
    public T findByEmail(String email); 
} 

यह ठीक चलाता है:

@RequestMapping(value="/persons",method = RequestMethod.POST) 
@ResponseBody 
public ResponseEntity<List<Person>> saveUsers(@RequestBody List<Person> persons) { 
     persons = (List<Person>) userRepository.save(persons); 
     return new ResponseEntity<List<Person>>(persons, HttpStatus.OK); 
} 

और यहाँ भंडार है । कोड चलाने के दौरान मैं निम्नलिखित लॉग देखता हूं।

Hibernate: insert into user (email, firstname, lastname, user_type) values (?, ?, ?, 'Person') 
Hibernate: insert into user (email, firstname, lastname, user_type) values (?, ?, ?, 'Person') 
Hibernate: insert into user (email, firstname, lastname, user_type) values (?, ?, ?, 'Person') 
Hibernate: insert into user (email, firstname, lastname, user_type) values (?, ?, ?, 'Person') 

ऐसा लगता है कि, डेटाबेस 4 बार मारा जाता है। मैंने सहेजने (कार्यान्वयन योग्य ई) विधि के कार्यान्वयन को देखा है, जहां प्रत्येक इकाई को बचाने के लिए लूप चलाया जाता है। तो, मेरे सवालों का है:

  1. डीबी 4 बार मारा जाता है?
  2. यदि ऐसा है, तो क्या यह 1 डीबी हिट (स्प्रिंग डेटा जेपीए का उपयोग करके) में किया जा सकता है? ऐसा करने से, क्या बड़ी संख्या में रिकॉर्ड डालने के मामले में यह प्रदर्शन को बढ़ावा देगा?
+0

हां, आप 4 बार डीबी मार रहे हैं। यदि आप हाईलोड अनुप्रयोगों के साथ काम कर रहे हैं, तो अच्छा विचार हाइबरनेट बैच का उपयोग करना होगा या ... मल्टीथ्रेडिंग का उपयोग करके अपना बैच ऑपरेशन करें। – Reborn

+0

यह निर्भर करता है कि आप डेटाबेस से टकराने 4 बार से क्या मतलब है - आप शायद एक कनेक्शन है, जहां वास्तविक लागत की संभावना कनेक्शन – farrellmr

+0

@farrellmr पैदा कर रही है पर 4 आवेषण है है: मैं भी यही लगता है। तो, प्रदर्शन बिंदु से जेडीबीसी के तैयार स्टेटमेंट के एडबैच() और executebatch() से रिकॉर्ड अधिक सम्मिलित करने का उपरोक्त समाधान है? –

उत्तर

4

हां, आप डेटा को चार बार पूछ रहे हैं।

आप Hibernate Batching को लागू करके एक बैच स्टेटमेंट में सम्मिलन कर सकते हैं। विशेष रूप से, batch inserts प्रदर्शन करने पर एक नज़र डालें। बैच आवेषण का उपयोग करके, आपको सत्र में flush() और clear() विधियों को स्पष्ट कॉल करके मैन्युअल रूप से सत्र को नियंत्रित करना होगा।

इसके अलावा, उचित बैच आकार Hibernate Batching Properties जैसे (डिफ़ॉल्ट 5) स्थापित करने पर विचार, और यदि लागू हो, अनुमति हाइबरनेट करने के लिए फिर से आदेश सम्मिलन और अद्यतन बैच बयान निर्माण करने से पहले:

hibernate.jdbc.batch_size = 25 
hibernate.order_inserts = true 
hibernate.order_updates = true 
+0

मैंने आपके द्वारा सुझाए गए प्रयासों की कोशिश की लेकिन परिणाम वही था। 'अंतिम सूची savedEntities = नया ArrayList (entities.size()); \t \t int i = 0; \t \t (टी टी: इकाइयों) { \t \t \t savedEntities.add (persistOrMerge (टी)); \t \t \t i ++; \t \t \t अगर (i% batchSize == 0) { \t \t \t \t // आवेषण का एक बैच फ्लश और रिलीज स्मृति। \t \t \t \t entityManager.flush(); \t \t \t \t entityManager.clear(); \t \t \t} \t \t} \t \t वापसी savedEntities; \t} \t निजी <टी फैली उपयोगकर्ता> टी persistOrMerge (टी टी) { \t \t अगर (t.getId() == 0) { \t \t entityManager.persist (टी); \t \t वापसी टी; \t \t} अन्य { \t \t वापसी इकाईManager.merge (टी); \t \t} \t} ' –

+0

फ़ॉर्मेटिंग के लिए खेद है। –

1

the docs on Hibernate Batching से :

हाइबरनेट जेडीबीसी स्तर पर पारदर्शी रूप से सम्मिलित बैचिंग अक्षम करता है यदि आप पहचान पहचानकर्ता जनरेटर का उपयोग करते हैं।

तो, Person एक Identity जनरेटर का उपयोग कर रहा है, तो बैचिंग (के रूप में Sequence जनरेटर या TABLE जनरेटर के खिलाफ) नहीं होगी। ऐसा क्यों है, इसके बारे में अधिक जानकारी के लिए this section देखें।

संबंधित मुद्दे