EntityManager.merge()
নতুন অবজেক্ট .োকাতে এবং বিদ্যমানগুলি আপডেট করতে পারে।
কেন কেউ ব্যবহার করতে চান persist()
(যা কেবলমাত্র নতুন অবজেক্ট তৈরি করতে পারে)?
EntityManager.merge()
নতুন অবজেক্ট .োকাতে এবং বিদ্যমানগুলি আপডেট করতে পারে।
কেন কেউ ব্যবহার করতে চান persist()
(যা কেবলমাত্র নতুন অবজেক্ট তৈরি করতে পারে)?
উত্তর:
যে কোনও উপায়ে একটি অস্তিত্বকে একটি PersistanceContext এ যুক্ত করবে, পার্থক্যটি আপনি সত্তার সাথে পরবর্তীকালে যা করেন তার মধ্যে পার্থক্য।
প্যারিস্ট একটি সত্তা উদাহরণ গ্রহণ করে, এটি প্রসঙ্গে যুক্ত করে এবং সেই দৃষ্টান্তটি পরিচালনা করে (যেমন সত্তার ভবিষ্যতে আপডেটগুলি ট্র্যাক করা হবে)।
মার্জটি পরিচালিত উদাহরণটি দেয় যা রাজ্যে একীভূত হয়েছিল। এটি পার্সিস্টিস্টন কনটেস্টে বিদ্যমান যা কিছু দেয় তা দেয় বা আপনার সত্তার একটি নতুন উদাহরণ তৈরি করে। যাইহোক, এটি সরবরাহ করা সত্তা থেকে রাষ্ট্রটিকে অনুলিপি করবে এবং পরিচালিত অনুলিপিটি ফিরিয়ে দেবে। আপনি যে উদাহরণটি পাস করেছেন তা পরিচালনা করা হবে না (আপনি যে কোনও পরিবর্তন করেন তা লেনদেনের অংশ হবে না - যদি আপনি আবার মার্জকে কল না করেন)। আপনি ব্যবহারের মাধ্যমে ফিরে আসা উদাহরণগুলি (পরিচালনা করতে পারেন) মাধ্যমে করতে পারেন।
হতে পারে একটি কোড উদাহরণ সাহায্য করবে।
MyEntity e = new MyEntity();
// scenario 1
// tran starts
em.persist(e);
e.setSomeField(someValue);
// tran ends, and the row for someField is updated in the database
// scenario 2
// tran starts
e = new MyEntity();
em.merge(e);
e.setSomeField(anotherValue);
// tran ends but the row for someField is not updated in the database
// (you made the changes *after* merging)
// scenario 3
// tran starts
e = new MyEntity();
MyEntity e2 = em.merge(e);
e2.setSomeField(anotherValue);
// tran ends and the row for someField is updated
// (the changes were made to e2, not e)
পরিস্থিতি 1 এবং 3 মোটামুটি সমান, তবে এমন কিছু পরিস্থিতি রয়েছে যেখানে আপনি পরিস্থিতি 2 ব্যবহার করতে চান।
merge
কোনও বস্তুর পরিচালনা করার আগে তার সম্পূর্ণ অনুলিপিটির কোনও পারফরম্যান্স হিট হয়েছে?
@GeneratedId
এটি 2 দৃশ্যে পেতে পারি?
স্থির থাকা এবং একত্রীকরণ দুটি ভিন্ন উদ্দেশ্যে হয় (তারা মোটেও বিকল্প নয়)।
(পার্থক্য তথ্য প্রসারিত সম্পাদিত)
জিদ:
একত্রিত করা:
দক্ষতা অব্যাহত রাখুন:
স্থির () শব্দার্থবিজ্ঞান:
উদাহরণ:
{
AnyEntity newEntity;
AnyEntity nonAttachedEntity;
AnyEntity attachedEntity;
// Create a new entity and persist it
newEntity = new AnyEntity();
em.persist(newEntity);
// Save 1 to the database at next flush
newEntity.setValue(1);
// Create a new entity with the same Id than the persisted one.
AnyEntity nonAttachedEntity = new AnyEntity();
nonAttachedEntity.setId(newEntity.getId());
// Save 2 to the database at next flush instead of 1!!!
nonAttachedEntity.setValue(2);
attachedEntity = em.merge(nonAttachedEntity);
// This condition returns true
// merge has found the already attached object (newEntity) and returns it.
if(attachedEntity==newEntity) {
System.out.print("They are the same object!");
}
// Set 3 to value
attachedEntity.setValue(3);
// Really, now both are the same object. Prints 3
System.out.println(newEntity.getValue());
// Modify the un attached object has no effect to the entity manager
// nor to the other objects
nonAttachedEntity.setValue(42);
}
সত্তা পরিচালকের যে কোনও নিবন্ধের জন্য এই উপায়ে কেবল 1 সংযুক্ত বস্তু বিদ্যমান।
আইডি সহ কোনও সত্তার জন্য মার্জ () হ'ল এমন কিছু:
AnyEntity myMerge(AnyEntity entityToSave) {
AnyEntity attached = em.find(AnyEntity.class, entityToSave.getId());
if(attached==null) {
attached = new AnyEntity();
em.persist(attached);
}
BeanUtils.copyProperties(attached, entityToSave);
return attached;
}
যদিও মাইএসকিউএল সংযুক্তির সাথে সংযুক্ত থাকলে () চালিয়ে যাওয়ার মতো দক্ষ হতে পারে () অন ডুপ্লিকেট কী আপডেটের বিকল্পের মাধ্যমে INSERT এ কল ব্যবহার করা, জেপিএ খুব উচ্চ স্তরের প্রোগ্রামিং এবং আপনি ধরে নিতে পারবেন না যে এটি সর্বত্রই ঘটবে।
em.persist(x)
সঙ্গে x = em.merge(x)
?
merge()
এছাড়াও একটি নিক্ষেপ করতে পারেনEntityExistsException
RuntimeException
, কিন্তু এটা Javadoc উল্লেখ নেই।
আপনি যদি নির্ধারিত জেনারেটরটি ব্যবহার করে থাকেন তবে অবিরতের পরিবর্তে মার্জটি ব্যবহার করা অপ্রয়োজনীয় এসকিউএল স্টেটমেন্টের কারণ হতে পারে , সুতরাং কার্যকারিতা প্রভাবিত করে।
এছাড়াও, পরিচালিত সংস্থাগুলির জন্য মার্জ কল কলটিও একটি ভুল যেহেতু পরিচালিত সংস্থাগুলি স্বয়ংক্রিয়ভাবে হাইবারনেট দ্বারা পরিচালিত হয় এবং পার্সেস্টি কনটেক্সট ফ্লাশ করার পরে নষ্ট চেকিং ব্যবস্থার মাধ্যমে তাদের রাষ্ট্রটি ডাটাবেস রেকর্ডের সাথে সুসংগত হয় ।
এই সমস্ত কীভাবে কাজ করে তা বোঝার জন্য আপনাকে প্রথমে জানতে হবে যে হাইবারনেট বিকাশকারী মানসিকতাটিকে এসকিউএল স্টেটমেন্ট থেকে সত্তার রাষ্ট্রের রূপান্তরগুলিতে স্থানান্তর করে ।
একবার কোনও সত্তা হাইবারনেট দ্বারা সক্রিয়ভাবে পরিচালিত হয়ে গেলে, সমস্ত পরিবর্তন স্বয়ংক্রিয়ভাবে ডাটাবেসে প্রচারিত হবে।
হাইবারনেট মনিটর বর্তমানে সংযুক্ত সত্তা। তবে কোনও সত্তা পরিচালিত হওয়ার জন্য, এটি অবশ্যই সঠিক সত্তা অবস্থায় থাকা উচিত।
জেপিএ স্টেট ট্রানজিশনগুলি আরও ভালভাবে বুঝতে, আপনি নিম্নলিখিত চিত্রটি কল্পনা করতে পারেন:
বা যদি আপনি হাইবারনেট নির্দিষ্ট API ব্যবহার করেন:
উপরের চিত্রগুলি দ্বারা চিত্রিত হিসাবে, একটি সত্তা নিম্নলিখিত চারটি রাজ্যের একটিতে থাকতে পারে:
নতুন (ক্ষণস্থায়ী)
একটি সদ্য নির্মিত বস্তু যা হাইবারনেট Session
(ওরফে Persistence Context
) এর সাথে কখনও যুক্ত হয় নি এবং কোনও ডাটাবেস টেবিল সারিতে ম্যাপ করা হয়নি তা নতুন (ক্ষণস্থায়ী) অবস্থায় বিবেচিত হয়।
অবিচল থাকার জন্য আমাদের হয় স্পষ্টভাবে EntityManager#persist
পদ্ধতিটি কল করতে হবে বা ট্রানজিটিভ অধ্যবসায়ের প্রক্রিয়াটি ব্যবহার করতে হবে।
অবিরাম (পরিচালিত)
একটি অবিচলিত সত্তা একটি ডাটাবেস টেবিল সারিটির সাথে যুক্ত হয়েছে এবং এটি বর্তমানে চলমান দৃistence়তা প্রসঙ্গে পরিচালনা করা হচ্ছে। এই জাতীয় সত্তায় যে কোনও পরিবর্তন করা হয়েছে তা সনাক্ত করে ডেটাবেজে প্রচার করা হচ্ছে (সেশন ফ্লাশ-সময় চলাকালীন)। হাইবারনেট সহ, আমাদের আর ইনসার্ট / আপডেট / বিবৃতি মুছে ফেলতে হবে না। হাইবারনেট একটি লেনদেনমূলক রাইট-ব্যাক ওয়ার্কিং স্টাইলকে নিয়োগ করে এবং পরিবর্তনগুলি খুব শেষ দায়ী মুহুর্তে, বর্তমান Session
ফ্লাশ-সময়ের সময়ে সিঙ্ক্রোনাইজ করা হয় ।
বিচ্ছিন্ন
একবার চলমান দৃistence়প্রত্যক্ষ প্রসঙ্গটি বন্ধ হয়ে গেলে পূর্ববর্তী সমস্ত পরিচালিত সত্তা বিচ্ছিন্ন হয়ে যায়। ধারাবাহিক পরিবর্তনগুলি আর ট্র্যাক করা হবে না এবং কোনও স্বয়ংক্রিয় ডাটাবেস সিঙ্ক্রোনাইজেশন ঘটবে না।
একটি সক্রিয় হাইবারনেট সেশনে একটি বিচ্ছিন্ন সত্তাকে সংযুক্ত করতে, আপনি নিম্নলিখিত বিকল্পগুলির মধ্যে একটি চয়ন করতে পারেন:
reattaching
হাইবারনেট (তবে জেপিএ ২.১ নয়) সেশন # আপডেট পদ্ধতির মাধ্যমে পুনরায় পাঠানো সমর্থন করে। একটি হাইবারনেট সেশন একটি প্রদত্ত ডাটাবেস সারিটির জন্য কেবল একটি সত্তা অবজেক্টকে যুক্ত করতে পারে। কারণ পার্সিস্টন কনটেক্সট একটি ইন-মেমরি ক্যাশে (প্রথম স্তরের ক্যাশে) হিসাবে কাজ করে এবং কেবলমাত্র একটি মান (সত্তা) প্রদত্ত কী (সত্তার ধরণ এবং ডাটাবেস শনাক্তকারী) এর সাথে সম্পর্কিত। বর্তমান হাইবারনেট সেশনের সাথে ইতিমধ্যে অন্য কোনও জেভিএম অবজেক্ট (একই ডাটাবেস সারিটির সাথে মিলছে) উপস্থিত না থাকলেই কোনও সত্তা পুনরায় সংযুক্ত করা যায়।
মার্জ
মার্জটি বিচ্ছিন্ন সত্তা রাষ্ট্রের (উত্স) একটি পরিচালিত সত্তা উদাহরণ (গন্তব্য) অনুলিপি করতে চলেছে। যদি মার্জিং সত্তার বর্তমান সেশনে কোনও সমতুল্য না থাকে তবে একটি ডাটাবেস থেকে আনা হবে। বিচ্ছিন্ন বস্তুর উদাহরণটি মার্জ অপারেশনের পরেও বিচ্ছিন্ন থাকতে থাকবে।
অপসারিত
যদিও জেপিএ দাবি করে যে পরিচালিত সত্তাগুলি কেবল অপসারণের অনুমতি দেওয়া হয়েছে, হাইবারনেট বিচ্ছিন্ন সত্তাও মুছে ফেলতে পারে (তবে কেবল একটি সেশন # মোছার পদ্ধতি কলের মাধ্যমে)। একটি সরানো সত্তা কেবল মুছে ফেলার জন্য নির্ধারিত হয়েছে এবং আসল ডাটাবেস ডিলিট বিবৃতিটি সেশন ফ্লাশ-সময় চলাকালীন কার্যকর করা হবে।
আমি লক্ষ্য করেছি যে আমি যখন ব্যবহার করেছি তখন আমি প্রত্যেকের জন্য em.merge
একটি SELECT
বিবৃতি পেয়েছিলাম INSERT
, এমনকী যখন জেপিএ আমার পক্ষে উত্পন্ন করার ক্ষেত্র ছিল না - প্রাথমিক কী ক্ষেত্রটি এমন একটি ইউআইডি ছিল যা আমি নিজেকে সেট করেছিলাম। আমি স্যুইচ করেছি em.persist(myEntityObject)
এবং তখন কেবল INSERT
বিবৃতি পেয়েছি ।
merge()
। আমার কাছে জটিল ভিউ সহ পোস্টগ্রাইএসকিউএল ডাটাবেস ছিল : বেশ কয়েকটি টেবিল থেকে ভিউ একত্রিত ডেটা (টেবিলগুলির অভিন্ন কাঠামো ছিল তবে বিভিন্ন নাম ছিল)। সুতরাং জেপিএ চেষ্টা করেছিল merge()
, কিন্তু আসলে জেপিএ প্রথম তৈরি করেছিল SELECT
(দেখার সেটিংসের কারণে ডাটাবেস বিভিন্ন টেবিল থেকে একই প্রাথমিক কী সহ বেশ কয়েকটি রেকর্ড ফিরিয়ে দিতে পারে!), তখন জেপিএ (হাইবারনেট একটি বাস্তবায়ন ছিল) ব্যর্থ হয়েছিল: একই কী সহ বেশ কয়েকটি রেকর্ড রয়েছে ( org.hibernate.HibernateException: More than one row with the given identifier was found
)। আমার ক্ষেত্রে persist()
আমাকে সাহায্য করেছে।
জেপিএ স্পেসিফিকেশন নিম্নলিখিত সম্পর্কে নিম্নলিখিত বলে persist()
।
তাহলে এক্স একটি বিচ্ছিন্ন বস্তুর হয়,
EntityExistsException
ফেলে দেওয়া হতে পারে জিদ অপারেশন প্রার্থনা করা হয়, অথবাEntityExistsException
বা অন্যPersistenceException
ফ্লাশ নিক্ষিপ্ত হতে পারে বা সময় কমিট।
সুতরাং persist()
অবজেক্টটি কোনও বিযুক্ত বস্তু হওয়া উচিত নয় যখন ব্যবহার করা উপযুক্ত হবে । আপনি কোডটি ছুড়ে ফেলতে পছন্দ করতে পারেন PersistenceException
যাতে এটি দ্রুত ব্যর্থ হয়।
স্পেসিফিকেশন অস্পষ্ট যদিও , একটি বস্তুর জন্য persist()
সেট করতে পারে @GeneratedValue
@Id
। merge()
তবে @Id
ইতিমধ্যে উত্পন্ন উত্স সহ অবশ্যই একটি বিষয় থাকতে হবে ।
merge()
তবে এর জন্য অবশ্যই @Id
ইতিমধ্যে উত্পন্ন সামগ্রীর সাথে একটি বিষয় থাকতে হবে । " যখনই সত্তা ম্যানেজার অবজেক্ট আইডির ক্ষেত্রের জন্য কোনও মান খুঁজে পায় না, তখন এটি ডিবিতে অবিচল (সন্নিবেশিত) থাকে।
মার্জ সম্পর্কে আরও কিছু বিশদ যা আপনাকে মেশিনটি অবিরত ব্যবহার করতে সহায়তা করবে:
মূল সত্তা ব্যতীত অন্য কোনও পরিচালিত দৃষ্টান্ত ফিরিয়ে দেওয়া একত্রীকরণ প্রক্রিয়ার একটি সমালোচনামূলক অঙ্গ। যদি একই সনাক্তকারী সহ কোনও সত্তা উদাহরণ ইতিমধ্যে অধ্যবসায় প্রসঙ্গে উপস্থিত থাকে তবে সরবরাহকারী একত্রীকরণের সত্তার সাথে তার রাষ্ট্রটিকে ওভাররাইট করবে তবে ইতিমধ্যে বিদ্যমান পরিচালিত সংস্করণটি অবশ্যই ক্লায়েন্টকে ফিরিয়ে দিতে হবে যাতে এটি হতে পারে ব্যবহার করা হয়েছে। সরবরাহকারীর যদি অধ্যবসায় প্রসঙ্গে কর্মচারী উদাহরণটি আপডেট না করে, তবে এই দৃষ্টান্তের কোনও উল্লেখ নতুন রাষ্ট্রের সাথে একীভূত হওয়ার সাথে মিলবে না।
যখন মার্জ () কোনও নতুন সত্তায় আহ্বান করা হয়, তখন এটি স্থির () ক্রিয়াকলাপের অনুরূপ আচরণ করে। এটি অধ্যবসায় প্রসঙ্গে ইন্টিটিটি যুক্ত করে তবে মূল সত্তা উদাহরণটি যুক্ত করার পরিবর্তে এটি একটি নতুন অনুলিপি তৈরি করে এবং পরিবর্তে সেই দৃষ্টান্তটি পরিচালনা করে। মার্জ () অপারেশন দ্বারা তৈরি করা অনুলিপিটি যদি অবিচ্ছিন্ন () পদ্ধতিতে অনুরোধ করা থাকে তবে তা অবিচল থাকে।
সম্পর্কের উপস্থিতিতে, মার্জ () অপারেশন পরিচালিত সত্তাকে আপডেট করার চেষ্টা করবে বিচ্ছিন্ন সত্তার দ্বারা রেফারেন্সযুক্ত সত্তাগুলির পরিচালিত সংস্করণগুলিতে point যদি সত্তার কোনও অবিচ্ছিন্ন পরিচয় নেই এমন কোনও জিনিসের সাথে সম্পর্ক থাকে তবে মার্জ অপারেশনের ফলাফল অপরিজ্ঞাত। কিছু সরবরাহকারী পরিচালিত অনুলিপিটি অ-অবিচলিত অবজেক্টের দিকে নির্দেশ করতে পারে, অন্যরা অবিলম্বে একটি ব্যতিক্রম নষ্ট করতে পারে। এই ক্ষেত্রে মার্জ () অপারেশনটি বিকল্পভাবে ক্যাসকেড করা যেতে পারে যাতে কোনও ব্যতিক্রম ঘটতে না পারে। আমরা এই বিভাগে পরে মার্জ () অপারেশনের ক্যাসকেডিং কভার করব। যদি কোনও সত্তা কোনও সরানো সত্তার দিকে চিহ্নিত করা হয় তবে একটি অবৈধআর্গুমেন্টএক্সেপশন ব্যতিক্রম নিক্ষেপ করা হবে।
অলস-লোডিং সম্পর্কগুলি মার্জ অপারেশনের একটি বিশেষ ক্ষেত্রে। যদি কোনও সত্তার আলাদা হওয়ার আগে অলস-লোডিং সম্পর্কটি ট্রিগার না করা হয়, সত্তাটি একীভূত হওয়ার পরে সেই সম্পর্কটিকে অগ্রাহ্য করা হবে। যদি পরিচালনা করার সময় সম্পর্কটি ট্রিগার করা হয়েছিল এবং সত্তাটি বিচ্ছিন্ন হওয়ার সময় বাতিল হয়ে যায়, সত্তার পরিচালিত সংস্করণটি একইভাবে সংযুক্তির সময় সম্পর্কটি সাফ করে দেবে ""
উপরোক্ত সমস্ত তথ্য মাইক কেইথ এবং মেরিক শনিকারিওল দ্বারা "প্রো জেপিএ 2 মাস্টারিং জাভা ™ পার্সোনালিটি এপিআই" থেকে নেওয়া হয়েছিল। অধ্যায় 6. বিভাগ বিচ্ছিন্নকরণ এবং মার্জ করা। এই বইটি আসলে লেখকরা জেপিএকে উত্সর্গীকৃত একটি দ্বিতীয় বই। এই নতুন বইয়ের অনেকগুলি নতুন তথ্য রয়েছে তারপরে প্রাক্তনটি। যারা জেপিএর সাথে মারাত্মকভাবে জড়িত হবে তাদের জন্য আমি এই বইটি পড়তে সত্যিই পুনরায় প্রত্যাশা করেছি। আমি আমার প্রথম উত্তর একনিষ্ঠভাবে পোস্ট করার জন্য দুঃখিত।
তার মাঝে আরো কিছু পার্থক্য আছে merge
এবং persist
(আমি আবার ঐ ইতিমধ্যে এখানে পোস্ট গনা কিছু থাকবে):
D1। merge
উত্তীর্ণ সত্তা পরিচালিত করে না, বরং পরিচালিত অন্য উদাহরণটি দেয়। persist
অন্যদিকে পাস করা সত্তাকে পরিচালিত করবে:
//MERGE: passedEntity remains unmanaged, but newEntity will be managed
Entity newEntity = em.merge(passedEntity);
//PERSIST: passedEntity will be managed after this
em.persist(passedEntity);
D2 গ্রাহকের। যদি আপনি কোনও সত্তা অপসারণ করেন এবং তারপরে সত্তাকে পিছনে রাখার সিদ্ধান্ত নেন তবে আপনি এটি কেবল অবিরাম () রেখেই করতে পারেন, কারণ merge
এটি নিক্ষেপ করবে IllegalArgumentException
।
থেকে D3। আপনি যদি নিজের আইডির ম্যানুয়ালি যত্ন নেওয়ার সিদ্ধান্ত নিয়েছেন (যেমন ইউআইডি ব্যবহার করে), তবে কোনও আইডিয়া থাকা অস্তিত্ব সত্ত্বার সন্ধানের জন্য একটি merge
ক্রিয়াকলাপ পরবর্তী SELECT
প্রশ্নের সন্ধান করবে , যখন persist
সেই প্রশ্নের প্রয়োজন নাও হতে পারে।
D4। এমন কিছু ক্ষেত্রে রয়েছে যখন আপনি কেবল আপনার কোডটিকে কল করে এমন কোডটি বিশ্বাস করেন না এবং কোনও ডেটা আপডেট হয় না তা নিশ্চিত করার জন্য, বরং সন্নিবেশ করা হয়েছে, আপনাকে অবশ্যই ব্যবহার করতে হবে persist
।
আমি আমার সত্তায় অলস লোডিং ব্যতিক্রমগুলি পেয়ে যাচ্ছিলাম কারণ আমি অধিবেশনকৃত একটি অলস লোড সংগ্রহটি অ্যাক্সেস করার চেষ্টা করছিলাম।
আমি যা করব তা একটি পৃথক অনুরোধে ছিল, সেশন থেকে সত্তাটি পুনরুদ্ধার করুন এবং তারপরে আমার জেএসপি পৃষ্ঠায় একটি সংকলন অ্যাক্সেস করার চেষ্টা করুন যা সমস্যাযুক্ত ছিল।
এটিকে হ্রাস করতে, আমি একই নিয়ামকটি আমার নিয়ামকটিতে আপডেট করেছি এবং এটি আমার জেএসপিতে দিয়েছি, যদিও আমি কল্পনা করেছিলাম যে আমি যখন সেশনে পুনরায় সঞ্চয় করেছিলাম যে এটিও অ্যাক্সেসযোগ্য হবে এবং SessionScope
একটি নিক্ষেপ করবে না LazyLoadingException
, উদাহরণ 2:
নিম্নলিখিতটি আমার পক্ষে কাজ করেছে:
// scenario 2 MY WAY
// tran starts
e = new MyEntity();
e = em.merge(e); // re-assign to the same entity "e"
//access e from jsp and it will work dandy!!
আমি হাইবারনেট ডক্স আলোকিতকরণ থেকে এই ব্যাখ্যাটি পেয়েছি, কারণ এগুলিতে একটি ব্যবহারের মামলা রয়েছে:
মার্জ () ব্যবহার এবং শব্দার্থকতা নতুন ব্যবহারকারীদের জন্য বিভ্রান্তিকর বলে মনে হচ্ছে। প্রথমত, যতক্ষণ না আপনি অন্য নতুন সত্তা পরিচালকের এক সত্তা ব্যবস্থাপকটিতে লোড হওয়া অবজেক্ট স্টেট ব্যবহার করার চেষ্টা করছেন না, আপনার একেবারে মার্জ () ব্যবহার করার দরকার নেই । কিছু সম্পূর্ণ অ্যাপ্লিকেশন কখনই এই পদ্ধতিটি ব্যবহার করবে না।
সাধারণত মার্জ () নিম্নলিখিত দৃশ্যে ব্যবহৃত হয়:
- অ্যাপ্লিকেশনটি প্রথম সত্তা ব্যবস্থাপকের মধ্যে একটি বস্তু লোড করে
- অবজেক্টটি উপস্থাপনা স্তর পর্যন্ত প্রেরণ করা হয়
- কিছু সংশোধন বস্তু তৈরি করা হয়
- অবজেক্টটি ব্যবসায়ের লজিক লেয়ারে ফিরে যায়
- অ্যাপ্লিকেশনটি দ্বিতীয় সত্তা পরিচালকের মধ্যে মার্জ () কল করে এই পরিবর্তনগুলি অব্যাহত রাখে
এখানে মার্জ করার সঠিক অর্থ ():
- যদি বর্তমানে অধ্যবসায় প্রসঙ্গে জড়িত একই পরিচয়কারীর সাথে যদি কোনও পরিচালিত উদাহরণ থাকে তবে প্রদত্ত বস্তুর স্থিতিটি পরিচালিত দৃষ্টান্তে অনুলিপি করুন
- যদি বর্তমানে অধ্যবসায় প্রসঙ্গে জড়িত কোনও পরিচালিত উদাহরণ না থাকে তবে এটি ডাটাবেস থেকে লোড করার চেষ্টা করুন বা একটি নতুন পরিচালিত উদাহরণ তৈরি করুন
- পরিচালিত দৃষ্টান্তটি ফিরে আসে
- প্রদত্ত উদাহরণটি অধ্যবসায় প্রসঙ্গে জড়িত না, এটি বিচ্ছিন্ন থাকে এবং সাধারণত তা বাতিল করা হয়
থেকে: http://docs.jboss.org/hibernate/entitymanager/3.6/references/en/html/objectstate.html
উত্তরে গিয়ে। ক্যাসকেড 'এবং আইডি জেনারেশন সম্পর্কিত কিছু বিবরণ অনুপস্থিত। প্রশ্ন দেখুন
এছাড়াও, এটি উল্লেখযোগ্য যে আপনার Cascade
মার্জ এবং অবিরত করার জন্য পৃথক টীকা থাকতে পারে : Cascade.MERGE
এবং Cascade.PERSIST
যা ব্যবহৃত পদ্ধতি অনুসারে চিকিত্সা করা হবে।
অনুমানটি আপনার বন্ধু;)
জাভা প্লাটফর্মে নির্মিত এন্টারপ্রাইজ অ্যাপ্লিকেশনগুলির ডোমেনে জেপিএ অনিন্দ্যভাবে দুর্দান্ত সরলকরণ। একজন ডেভলপার হিসাবে যাকে জে 2 ই ই-তে পুরানো সত্তার মটরশুটিগুলির জটিলতাগুলি সহ্য করতে হয়েছিল আমি জাভা ইই স্পেসিফিকেশনের মধ্যে জেপিএর অন্তর্ভুক্তিটিকে একটি বড় লিপ ফরোয়ার্ড হিসাবে দেখছি। যাইহোক, জেপিএ বিশদগুলির গভীরতর গভীরতা অবলম্বন করার সময় আমি এমন জিনিসগুলি পাই যা এত সহজ নয়। এই নিবন্ধে আমি সত্ত্বা ম্যানেজারের একত্রীকরণের সাথে তুলনা করেছি এবং এমন পদ্ধতি অব্যাহত রেখেছি যার ওভারল্যাপিং আচরণটি শুধুমাত্র একটি নবজাতকের জন্যই বিভ্রান্তি সৃষ্টি করতে পারে। তদুপরি আমি একটি সাধারণীকরণের প্রস্তাব করি যা উভয় পদ্ধতিকেই আরও সাধারণ পদ্ধতির একত্রিত করার বিশেষ ক্ষেত্র হিসাবে দেখায়।
সত্তা সত্তা
মার্জ পদ্ধতির বিপরীতে অবিচলিত পদ্ধতিটি বেশ সোজা এবং স্বজ্ঞাত। অবিচলিত পদ্ধতি ব্যবহারের সর্বাধিক সাধারণ পরিস্থিতি নিম্নরূপে সংক্ষিপ্ত করা যেতে পারে:
"সত্তা শ্রেণীর একটি নতুন নির্মিত উদাহরণ অবিচলিত পদ্ধতিতে পাস করা হয় this এই পদ্ধতিটি ফিরে আসার পরে সত্তাটি পরিচালনা করা হয় এবং ডাটাবেসে সন্নিবেশের জন্য পরিকল্পনা করা হয় the এটি লেনদেনটি কমিট হওয়ার আগে বা ফ্ল্যাশ পদ্ধতিটি কল করার সময় ঘটতে পারে। পার্সিস্ট ক্যাসকেড কৌশলের সাথে চিহ্নিত সম্পর্কের মাধ্যমে সত্তা যদি অন্য সত্তাকে উল্লেখ করে তবে এই পদ্ধতিটিও এটি প্রয়োগ করা হয়। "
স্পেসিফিকেশন বিশদগুলিতে আরও যায়, তবে এগুলি মনে রাখা গুরুত্বপূর্ণ নয় কারণ এই বিবরণগুলি কেবল কম বা কম বিদেশী পরিস্থিতিতে আবৃত।
সত্তা একত্রিত করা হচ্ছে
অধ্যবসায়ের তুলনায়, সংযুক্তির আচরণের বর্ণনা এত সহজ নয়। কোনও দৃশ্যের মূল পরিস্থিতি নেই, যেমনটি এটি অব্যাহত রাখার ক্ষেত্রে রয়েছে এবং একটি প্রোগ্রামারকে অবশ্যই একটি সঠিক কোড লেখার জন্য সমস্ত পরিস্থিতিতে মনে রাখতে হবে। আমার কাছে মনে হয় যে জেপিএ ডিজাইনাররা এমন কোনও পদ্ধতি রাখতে চেয়েছিলেন যার প্রাথমিক উদ্বেগ বিচ্ছিন্ন সংস্থাগুলি পরিচালনা করবে (মূলত নতুনভাবে তৈরি হওয়া সত্তাগুলির সাথে বিস্তৃত পদ্ধতিটির বিপরীতে)) মার্জ পদ্ধতির প্রধান কাজটি রাষ্ট্র থেকে স্থানান্তর করা অবিচলিত সত্তা (আর্গুমেন্ট হিসাবে পাস করা) দৃ managed়তা প্রসঙ্গে তার পরিচালিত প্রতিরূপে। এই টাস্কটি অবশ্য বেশ কয়েকটি দৃশ্যে বিভক্ত হয়ে গেছে যা সামগ্রিক পদ্ধতির আচরণের স্বাক্ষরতা আরও খারাপ করে দেয়।
জেপিএ নির্দিষ্টকরণ থেকে অনুচ্ছেদের পুনরাবৃত্তি করার পরিবর্তে আমি একটি ফ্লো ডায়াগ্রাম প্রস্তুত করেছি যা মার্জ পদ্ধতির আচরণের চিত্রগতভাবে চিত্রিত করে:
সুতরাং, কখন আমার অবিরাম ব্যবহার করা উচিত এবং কখন মার্জ করা উচিত?
জিদ করা
একত্রিত করা
পরিস্থিতি এক্স:
টেবিল: স্পিটার (এক), টেবিল: স্পিটলস (অনেক) (স্পিটলস একটি এফকে: স্পিটার_আইডির সাথে সম্পর্কের মালিক)
এই দৃশ্যের সংরক্ষণে ফলাফল: দ্য স্পিটার এবং উভয় স্পিটলস যেমন একই স্পিটারের মালিকানাধীন।
Spitter spitter=new Spitter();
Spittle spittle3=new Spittle();
spitter.setUsername("George");
spitter.setPassword("test1234");
spittle3.setSpittle("I love java 2");
spittle3.setSpitter(spitter);
dao.addSpittle(spittle3); // <--persist
Spittle spittle=new Spittle();
spittle.setSpittle("I love java");
spittle.setSpitter(spitter);
dao.saveSpittle(spittle); //<-- merge!!
পরিস্থিতি ওয়াই:
এটি স্পিটারকে বাঁচাবে, ২ টি স্পিটলস বাঁচাবে কিন্তু তারা একই স্পিটারকে রেফারেন্স করবে না!
Spitter spitter=new Spitter();
Spittle spittle3=new Spittle();
spitter.setUsername("George");
spitter.setPassword("test1234");
spittle3.setSpittle("I love java 2");
spittle3.setSpitter(spitter);
dao.save(spittle3); // <--merge!!
Spittle spittle=new Spittle();
spittle.setSpittle("I love java");
spittle.setSpitter(spitter);
dao.saveSpittle(spittle); //<-- merge!!
আরেকটি পর্যবেক্ষণ:
merge()
আপনার টেবিলটিতে ইতিমধ্যে যখন কোনও আইডি সহ কোনও রেকর্ড উপস্থিত থাকে তবে কেবলমাত্র একটি স্বয়ংক্রিয় উত্পাদিত আইডি (পরীক্ষিত IDENTITY
এবং SEQUENCE
) এর বিষয়ে যত্নশীল হবে । যে ক্ষেত্রে merge()
রেকর্ড আপডেট করার জন্য চেষ্টা করবে। তবে, যদি কোনও আইডি অনুপস্থিত বা বিদ্যমান রেকর্ডগুলির সাথে মেলে না, তবে merge()
এটি সম্পূর্ণরূপে উপেক্ষা করবে এবং একটি ডিবিকে একটি নতুন বরাদ্দ করতে বলবে। এটি কখনও কখনও প্রচুর বাগের উত্স হয়। merge()
নতুন রেকর্ডের জন্য কোনও আইডি জোর করে ব্যবহার করবেন না ।
persist()
অন্যদিকে এটি আপনাকে কোনও আইডি পাস করতে দেয় না। এটি সঙ্গে সঙ্গে ব্যর্থ হবে। আমার ক্ষেত্রে, এটি:
এর দ্বারা ঘটেছে: org.hibernate.Pers ContinObjectException: বিচ্ছিন্নভাবে সত্তাটি অস্তিত্ব বজায় রেখেছিল
হাইবারনেট-জেপা জাভাদোকের একটি ইঙ্গিত রয়েছে:
ছোঁড়ার : javax.persistence.EntityExistsException - যদি সত্তা ইতিমধ্যেই বিদ্যমান। (সত্তা ইতিমধ্যে বিদ্যমান থাকলে, অবিচ্ছিন্ন ক্রিয়াকলাপটি চালিত হলে অ্যান্টিএক্সজিস্ট এক্সেক্সশনটি নিক্ষেপ করা হতে পারে, বা সত্তা এক্সটিক্স এক্সপেনশন বা অন্য কোনও প্যাসিস্টিপশনটি ফ্ল্যাশ বা কমিট টাইমে নিক্ষেপ করা হতে পারে))
persist()
এটির একটি আইডি রয়েছে বলে অভিযোগ করবেন না, একই আইডি সহ কিছু ইতিমধ্যে ডাটাবেসে থাকলে অভিযোগ করে।
আপনি এখানে যখন ব্যবহার করার জন্য পরামর্শ আসতে পারেন জিদ এবং কখন ব্যবহার করতে একত্রীকরণ । আমি মনে করি এটি পরিস্থিতি নির্ভর করে: আপনার একটি নতুন রেকর্ড তৈরি করা কতটা সম্ভব এবং অবিরাম ডেটা পুনরুদ্ধার করা কতটা কঠিন is
ধরে নেওয়া যাক আপনি একটি প্রাকৃতিক কী / সনাক্তকারী ব্যবহার করতে পারেন।
ডেটা বজায় রাখা দরকার, তবে একবারে একবারে একটি রেকর্ড উপস্থিত থাকে এবং একটি আপডেটের জন্য বলা হয়। এক্ষেত্রে আপনি অবিরাম চেষ্টা করতে পারেন এবং এটি যদি কোনও এনটিটি এক্সজিস্ট এক্সেক্সেশনটি ছুড়ে ফেলে তবে আপনি এটি সন্ধান করুন এবং ডেটাটি একত্রিত করুন:
চেষ্টা করুন {MManager.persist (সত্তা)}
ধরা (সত্তাজনিত এক্সেপশন ব্যতিক্রম) {/ * পুনরুদ্ধার করুন এবং মার্জ করুন * /
বিদ্যমান তথ্য আপডেট করা দরকার, তবে একবারে এই তথ্যের কোনও রেকর্ড নেই। এক্ষেত্রে আপনি এটি সন্ধান করুন এবং সত্তাটি অনুপস্থিত থাকলে অবিরাম চেষ্টা করুন:
সত্তা = সত্তা -Manager.find (কী);
যদি (সত্তা == নাল) {MManager.persist (সত্তা); }
অন্য {/ * মার্জ * /
যদি আপনার কাছে প্রাকৃতিক কী / শনাক্তকারী না থাকে তবে সত্তাটি রয়েছে কি না বা কীভাবে এটি সন্ধান করবেন তা নির্ধারণ করার জন্য আপনার আরও শক্ত সময় হবে।
মার্জগুলি দুটি উপায়েও মোকাবেলা করা যেতে পারে:
ডিবিতে যুক্ত করার জন্য অবিরত (সত্তা) সম্পূর্ণ নতুন সত্তার সাথে ব্যবহার করা উচিত (যদি সত্তা ইতিমধ্যে ডিবিতে বিদ্যমান থাকে তবে সত্তা এক্সটেক্সিপশন থ্রো থাকবে)।
সত্তাটি আলাদা করা হয় এবং পরিবর্তন করা হয় তবে একত্রীকরণটিকে দৃ pers়তা প্রসঙ্গে ফিরিয়ে আনতে মার্জ (সত্তা) ব্যবহার করা উচিত।
সম্ভবত অবিচ্ছিন্নভাবে INSERT বর্গক্ষেত্র বিবৃতি উত্পন্ন করছে এবং UPDATE বর্গ স্টেটমেন্টটি মার্জ করবে (তবে আমি নিশ্চিত নই)।