EntityManager.merge()
නව වස්තු ඇතුළු කිරීමට සහ පවතින ඒවා යාවත්කාලීන කිරීමට හැකිය.
යමෙකුට භාවිතා කිරීමට අවශ්ය වන්නේ ඇයි persist()
(එයට නව වස්තු පමණක් නිර්මාණය කළ හැකිය)?
EntityManager.merge()
නව වස්තු ඇතුළු කිරීමට සහ පවතින ඒවා යාවත්කාලීන කිරීමට හැකිය.
යමෙකුට භාවිතා කිරීමට අවශ්ය වන්නේ ඇයි persist()
(එයට නව වස්තු පමණක් නිර්මාණය කළ හැකිය)?
Answers:
කෙසේ හෝ ස්ථිරසාර තත්වයකට වස්තුවක් එකතු කරනු ඇත, වෙනස වන්නේ ඔබ පසුව එම ආයතනය සමඟ කරන දෙයයි.
පර්සිස්ට් විසින් වස්තුවක් නිදසුනක් ගෙන, එය සන්දර්භයට එකතු කර එම අවස්ථාව කළමනාකරණය කරයි (එනම් අනාගත ආයතනයේ යාවත්කාලීන කිරීම් නිරීක්ෂණය කරනු ලැබේ).
ඒකාබද්ධ කිරීම මඟින් රාජ්යය ඒකාබද්ධ කළ කළමනාකරණ අවස්ථාව නැවත ලබා දේ. එය PersistenceContext හි පවතින දෙයක් නැවත ලබා දෙයි හෝ ඔබේ ආයතනයේ නව අවස්ථාවක් නිර්මාණය කරයි. ඕනෑම අවස්ථාවක, එය සැපයූ ආයතනයෙන් රාජ්යය පිටපත් කර කළමනාකරණය කළ පිටපතක් ලබා දෙනු ඇත. ඔබ සමත් වූ අවස්ථාව කළමනාකරණය නොකෙරේ (ඔබ කරන ඕනෑම වෙනස්කමක් ගනුදෙනුවේ කොටසක් නොවනු ඇත - ඔබ නැවත ඒකාබද්ධ කිරීම යැයි නොකියන්නේ නම්). ඔබට නැවත භාවිතා කළ උදාහරණය භාවිතා කළ හැකිය (කළමනාකරණය කළ එකක්).
සමහර විට කේත උදාහරණයක් උපකාරී වනු ඇත.
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 භාවිතා කිරීමට අවශ්ය අවස්ථා තිබේ.
නොනැසී පැවතීම හා ඒකාබද්ධ කිරීම වෙනස් අරමුණු දෙකක් සඳහා වේ (ඒවා කිසිසේත්ම විකල්ප නොවේ).
(වෙනස්කම් තොරතුරු පුළුල් කිරීම සඳහා සංස්කරණය කරන ලදි)
නොනැසී පවතිනවා:
ඒකාබද්ධ කිරීම:
දිගටම () කාර්යක්ෂමතාව:
දිගටම () අර්ථ නිරූපණය:
උදාහරණයක්:
{
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;
}
MySQL ඒකාබද්ධ කිරීම () සමඟ සම්බන්ධ වී ඇත්නම් () අඛණ්ඩව () ඔන් ඩුප්ලිකේට් කේ යාවත්කාලීන කිරීමේ විකල්පය සමඟ INSERT වෙත ඇමතුමක් භාවිතා කිරීම තරම් කාර්යක්ෂම විය හැකි වුවද, JPA ඉතා ඉහළ මට්ටමේ වැඩසටහන්කරණයක් වන අතර මෙය සෑම තැනකම සිදුවනු ඇතැයි ඔබට සිතිය නොහැකිය.
em.persist(x)
කළ x = em.merge(x)
හැකිද?
merge()
ද විසි හැකිEntityExistsException
RuntimeException
හි සඳහන් නොවේ.
ඔබ පවරා ඇති උත්පාදක යන්ත්රය භාවිතා කරන්නේ නම්, නොනැසී පැවතීම වෙනුවට ඒකාබද්ධ කිරීම අතිරික්ත SQL ප්රකාශයක් ඇති කළ හැකි අතර එම නිසා කාර්ය සාධනය කෙරෙහි බලපායි.
එසේම, කළමනාකරණය ආයතන සඳහා වෙන්කර ඇතත්, රාජ්ය සේවකයින්ට ඇත්තටම ඉල්ලා කළමනාකරණය ආයතන ස්වයංක්රීයව හයිබනේට් විසින් කළමනාකරණය කරන අතර ඔවුන්ගේ රාජ්ය විසින් දත්ත සමුදා වාර්තා සමඟ සමමුහුර්තකරණය කර ඇත සිට වැරැද්දක් ද යාන්ත්රණයක් පරීක්ෂා අපිරිසිදු මත අඛන්ඩ සංදර්භය මල්ලාවි .
මේ සියල්ල ක්රියාත්මක වන්නේ කෙසේද යන්න අවබෝධ කර ගැනීම සඳහා, ඔබ මුලින්ම දැනගත යුත්තේ හයිබර්නේට් විසින් සංවර්ධකයාගේ මානසිකත්වය SQL ප්රකාශයන්ගෙන් වස්තු රාජ්ය සංක්රාන්ති වෙත මාරු කරන බවයි.
හයිබර්නේට් විසින් ආයතනයක් සක්රියව කළමනාකරණය කළ පසු, සියලු වෙනස්කම් ස්වයංක්රීයව දත්ත ගබඩාවට ප්රචාරය වේ.
දැනට අමුණා ඇති ආයතන ශිශිර මොනිටර. නමුත් ආයතනයක් කළමනාකරණය වීමට නම් එය නිවැරදි වස්තු තත්වයේ තිබිය යුතුය.
JPA තත්ව සංක්රාන්තිය වඩා හොඳින් අවබෝධ කර ගැනීම සඳහා, ඔබට පහත රූප සටහන දෘශ්යමාන කළ හැකිය:
හෝ ඔබ ශිශිර නිශ්චිත API භාවිතා කරන්නේ නම්:
ඉහත රූපසටහන් වලින් පැහැදිලි වන පරිදි, වස්තුවක් පහත සඳහන් ප්රාන්ත හතරෙන් එකක් විය හැකිය:
නව (අස්ථිර)
අළුතින් සාදන ලද වස්තුවක් මෙතෙක් ශිශිර Session
(අකා Persistence Context
) සමඟ සම්බන්ධ වී නැති අතර කිසිදු දත්ත සමුදා වගු පේළියකට සිතියම් ගත කර නොමැති අතර එය නව (අස්ථිර) තත්වයේ ඇතැයි සැලකේ.
නොපසුබට වීමට නම් අපි EntityManager#persist
ක්රමවේදය පැහැදිලිව අමතන්න හෝ සංක්රාන්ති නොනැසී පවත්නා යාන්ත්රණය භාවිතා කළ යුතුය.
නිරන්තර (කළමනාකරණය)
අඛණ්ඩ වස්තුවක් දත්ත සමුදා වගු පේළියක් සමඟ සම්බන්ධ වී ඇති අතර එය කළමනාකරණය කරනු ලබන්නේ දැනට ක්රියාත්මක වන නොනැසී පවත්නා සන්දර්භය මගිනි. එවැනි ආයතනයක සිදුකරන ලද කිසියම් වෙනසක් හඳුනාගෙන දත්ත සමුදායට ප්රචාරය කරනු ඇත (සැසිය නළ කාලය තුළ). ශිශිරතාරක සමඟ, අපට තවදුරටත් INSERT / UPDATE / DELETE ප්රකාශ ක්රියාත්මක කිරීමට අවශ්ය නොවේ. ශිශිරතාරක ගනුදෙනු ලිවීමේ පිටුපස වැඩ කිරීමේ ශෛලියක් භාවිතා කරන අතර වෙනස්කම් වර්තමාන Session
ෆ්ලෂ් කාලය තුළ අවසාන වගකීම් මොහොතේදී සමමුහුර්ත වේ.
වෙන් කර ඇත
දැනට ක්රියාත්මක වන නොනැසී පවත්නා සන්දර්භය වසා දැමූ පසු, කලින් කළමනාකරණය කළ සියලුම ආයතන වෙන් වී යයි. අනුක්රමික වෙනස්කම් තවදුරටත් සොයා නොගන්නා අතර ස්වයංක්රීය දත්ත සමුදා සමමුහුර්ත කිරීමක් සිදු නොවේ.
වෙන්වූ ආයතනයක් සක්රීය ශිශිර සැසියකට සම්බන්ධ කිරීම සඳහා, ඔබට පහත විකල්ප වලින් එකක් තෝරා ගත හැකිය:
නැවත සම්බන්ධ කිරීම
හයිබර්නේට් (නමුත් JPA 2.1 නොවේ) සැසිය # යාවත්කාලීන කිරීමේ ක්රමය හරහා නැවත සම්බන්ධ වීමට සහාය වේ. ශිශිර සැසියකට ලබා දිය හැක්කේ ලබා දී ඇති දත්ත සමුදා පේළියක් සඳහා එක් වස්තු වස්තුවක් පමණි. මෙයට හේතුව වන්නේ අඛණ්ඩ සන්දර්භය මතකයේ හැඹිලියක් ලෙස (පළමු මට්ටමේ හැඹිලිය) ක්රියා කරන අතර දී ඇති යතුරක් (වස්තු වර්ගය සහ දත්ත සමුදා හඳුනාගැනීමේ) සමඟ සම්බන්ධ වන්නේ එක් අගයක් (වස්තුවක්) පමණි. වස්තුවක් නැවත සම්බන්ධ කළ හැක්කේ වර්තමාන ශිශිර සැසිය සමඟ දැනටමත් සම්බන්ධ වී ඇති වෙනත් JVM වස්තුවක් (එකම දත්ත සමුදා පේළියට ගැලපීම) නොමැති නම් පමණි.
ඒකාබද්ධ කිරීම
ඒකාබද්ධ කිරීම මඟින් වෙන් කරන ලද වස්තු තත්වය (ප්රභවය) කළමනාකරණ ආයතන අවස්ථාවකට (ගමනාන්තය) පිටපත් කිරීමට යයි. වත්මන් සැසියේදී ඒකාබද්ධ කිරීමේ ආයතනයට සමානත්වයක් නොමැති නම්, එකක් දත්ත සමුදායෙන් ලබා ගනී. ඒකාබද්ධ කිරීමේ මෙහෙයුමෙන් පසුව පවා වෙන් කරන ලද වස්තු උදාහරණය දිගටම පවතිනු ඇත.
ඉවත් කරන ලදි
කළමනාකරණ ආයතන පමණක් ඉවත් කිරීමට අවසර දෙන ලෙස JPA ඉල්ලා සිටියද, ශිශිරතාරයට වෙන් කළ ආයතන මකා දැමිය හැකිය (නමුත් සැසිය # මකාදැමීමේ ක්රම ඇමතුමකින් පමණි). ඉවත් කරන ලද ආයතනයක් මකාදැමීම සඳහා පමණක් සැලසුම් කර ඇති අතර සත්ය දත්ත සමුදාය DELETE ප්රකාශය සැසි ෆ්ලෂ් කාලය තුළ ක්රියාත්මක වේ.
මා භාවිතා කරන විට em.merge
, ජේපීඒ මා වෙනුවෙන් ජනනය කරන කිසිදු ක්ෂේත්රයක් නොතිබුණද, SELECT
සෑම කෙනෙකුටම ප්රකාශයක් ලැබුණු බව මම දුටුවෙමි INSERT
- ප්රාථමික යතුරු ක්ෂේත්රය යනු මා විසින්ම සකසන ලද UUID ය. මම මාරු වී එකල ප්රකාශ em.persist(myEntityObject)
ලබා ගත්තා INSERT
.
merge()
. මා සතුව PostgreSQL දත්ත සමුදාය සංකීර්ණ දෘෂ්ටියක් ඇත : දර්ශනය වගු කිහිපයකින් ලබාගත් දත්ත (වගු වලට සමාන ව්යුහයක් ඇති නමුත් වෙනස් නම්). එබැවින් ජේපීඒ කිරීමට උත්සාහ කළ merge()
නමුත් ඇත්ත වශයෙන්ම ජේපීඒ මුලින්ම සාදන ලද්දේ SELECT
(දර්ශන සැකසීම් නිසා දත්ත සමුදාය එකම වගුවකින් එකම වගුවකින් විවිධ වගු වලින් ආපසු ලබා දිය හැකිය!), පසුව ජේපීඒ (ශිශිරතාරකය ක්රියාත්මක කිරීමකි) අසාර්ථක විය: එකම යතුර සහිත වාර්තා කිහිපයක් තිබේ (org.hibernate.HibernateException: More than one row with the given identifier was found
). මගේ නඩුවේදී persist()
මට උදව් විය.
JPA පිරිවිතරයන් පහත සඳහන් දේ ගැන persist()
පවසයි.
නම් X සඳහා වෙන් වස්තුව වන අතර, මෙම
EntityExistsException
මෙහෙයුම පළ කළහ ඇත, හෝ දිගටම විට දමනු කළ හැකEntityExistsException
හෝ වෙනත්PersistenceException
දෝර ප්රහාරයක් හෝ කාල සිදු කළ හැක.
එබැවින් වස්තුව වෙන්වූ වස්තුවක් නොවිය යුතුpersist()
විට භාවිතා කිරීම සුදුසු වේ. කේතය විසි කිරීමට ඔබ කැමති විය හැකි බැවින් එය වේගයෙන් අසමත් වේ.PersistenceException
නමුත් එම පිරිවිතර ද යන්න පැහැදිලි නැත ,persist()
මේ කිරීමටද @GeneratedValue
@Id
වස්තුවක් සඳහා. merge()
කෙසේ වෙතත් සමඟ වස්තුවක් තිබිය යුතුය@Id
දැනටමත් ජනනය .
merge()
කෙසේ වෙතත් @Id
දැනටමත් ජනනය කර ඇති වස්තුවක් තිබිය යුතුය . " EntityManager විසින් වස්තු හැඳුනුම්පත් ක්ෂේත්රය සඳහා වටිනාකමක් සොයා නොගත් විට, එය දිගටම (DB) ඇතුළත් වේ.
ඒකාබද්ධ කිරීම පිළිබඳ තවත් විස්තර කිහිපයක් දිගටම පවතින විට ඒකාබද්ධ කිරීම භාවිතා කිරීමට ඔබට උපකාරී වනු ඇත:
මුල් වස්තුව හැර වෙනත් කළමනාකරණ අවස්ථාවක් නැවත ලබා දීම ඒකාබද්ධ කිරීමේ ක්රියාවලියේ තීරණාත්මක කොටසකි. එකම අනන්යතාවය සහිත වස්තු සිද්ධියක් දැනටමත් පවතින සන්දර්භය තුළ තිබේ නම්, සැපයුම්කරු ඒකාබද්ධ වන වස්තුවේ තත්වය සමඟ එහි තත්වය නැවත ලියනු ඇත, නමුත් දැනටමත් පැවති කළමනාකරණ අනුවාදය සේවාදායකයා වෙත ආපසු ලබා දිය යුතුය. භාවිතා කර ඇත. ස්ථීර සන්දර්භය තුළ සැපයුම්කරු විසින් සේවක අවස්ථාව යාවත්කාලීන නොකළේ නම්, එම අවස්ථාව පිළිබඳ කිසියම් සඳහනක් නව රාජ්යය ඒකාබද්ධ කිරීම සමඟ නොගැලපේ.
නව වස්තුවක් මත ඒකාබද්ධ කිරීම () යෙදූ විට, එය නොනැසී පවතින () මෙහෙයුමට සමානය. එය අඛණ්ඩ සන්දර්භයට වස්තුව එකතු කරයි, නමුත් මුල් වස්තු උදාහරණය එකතු කරනවා වෙනුවට, එය නව පිටපතක් නිර්මාණය කර ඒ වෙනුවට එම අවස්ථාව කළමනාකරණය කරයි. ඒකාබද්ධ කිරීමේ () මෙහෙයුම මගින් නිර්මාණය කරන ලද පිටපත දිගටම පවතින්නේ එය මත අඛණ්ඩ () ක්රමය ක්රියාත්මක කළ ආකාරයට ය.
සම්බන්ධතා ඉදිරියේ, ඒකාබද්ධ කිරීමේ () මෙහෙයුම මඟින් වෙන් කරන ලද ආයතනය විසින් යොමු කරන ලද ආයතනවල කළමනාකරණ අනුවාදයන් වෙත යොමු කිරීම සඳහා කළමනාකරණ ආයතනය යාවත්කාලීන කිරීමට උත්සාහ කරනු ඇත. අඛණ්ඩ අනන්යතාවයක් නොමැති වස්තුවක් සමඟ ආයතනයට සම්බන්ධතාවයක් තිබේ නම්, ඒකාබද්ධ කිරීමේ මෙහෙයුමේ ප්රති come ලය නිර්වචනය කර නැත. සමහර සැපයුම්කරුවන් විසින් කළමනාකරණ පිටපත නොනවතින වස්තුව වෙත යොමු කිරීමට ඉඩ දිය හැකි අතර අනෙක් අය වහාම ව්යතිරේකයක් විසි කළ හැකිය. ව්යතිරේකයක් සිදුවීම වැළැක්වීම සඳහා ඒකාබද්ධ කිරීමේ () මෙහෙයුම මෙම අවස්ථා වලදී විකල්ප ලෙස අවලංගු කළ හැකිය. ඒකාබද්ධ කිරීමේ () මෙහෙයුමේ කඳුරැල්ල අපි මෙම කොටසේ පසුව ආවරණය කරන්නෙමු. කිසියම් ආයතනයක් ඒකාබද්ධ කළ විට එය ඉවත් කළ ආයතනයකට යොමු වුවහොත්, නීති විරෝධී ආරෝපණ ව්යතිරේකයක් විසි කරනු ලැබේ.
කම්මැලි පැටවීමේ සම්බන්ධතා ඒකාබද්ධ කිරීමේ මෙහෙයුමේ විශේෂ අවස්ථාවකි. කම්මැලි පැටවීමේ සම්බන්ධතාවයක් වස්තුවක් වෙන්වීමට පෙර එය අවුලුවනු ලැබුවේ නැත්නම්, එම ආයතනය ඒකාබද්ධ වූ විට එම සම්බන්ධතාවය නොසලකා හරිනු ඇත. කළමනාකරණය අතරතුර සම්බන්ධතාවය අවුලුවනු ලැබූ අතර, එම ආයතනය වෙන්ව සිටියදී අහෝසි වී ඇත්නම්, කළමනාකරණයේ අනුවාදය ඒකාබද්ධ කිරීමේ දී සම්බන්ධතාවය නිෂ්කාශනය කරනු ඇත. ”
ඉහත සියලු තොරතුරු ලබාගෙන ඇත්තේ මයික් කීත් සහ මෙරික් ෂ්නිකාරියෝල් විසින් "Pro JPA 2 Mastering the Java ™ Persistence API" වෙතින් ය. අදියර 6. කොටස වෙන් කිරීම හා ඒකාබද්ධ කිරීම. මෙම පොත ඇත්ත වශයෙන්ම කතුවරුන් විසින් JPA සඳහා කැප කරන ලද දෙවන පොතකි. මෙම නව පොතේ නව තොරතුරු රාශියක් ඇත. ජේපීඒ සමඟ බැරෑරුම් ලෙස සම්බන්ධ වන අය සඳහා මෙම පොත කියවීමට මම සැබවින්ම නිර්දේශ කළෙමි. මගේ පළමු පිළිතුර නිර්නාමිකව පළ කිරීම ගැන මට කණගාටුයි.
merge
සහ අතර තවත් වෙනස්කම් කිහිපයක් තිබේpersist
(දැනටමත් මෙහි පළ කර ඇති අය නැවත ගණන් කරමි):
ඩී 1. 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);
ඩී 2. ඔබ ඒකකයක්, ඉවත් කිරීම හා පසුව ආයතනයක් නැවත දිගටම කිරීමට අදහස් කරන්නේ නම්, ඔබ පමණක් දිගටම () සමග, නිසා කරන්න පුළුවන් merge
විසිකිරීම ඇත IllegalArgumentException
.
ඩී 3. ඔබගේ හැඳුනුම්පත් (උදා: UUID භාවිතා කිරීමෙන්) ඔබ අතින් බලා ගැනීමට තීරණය කළේ නම්, එම merge
මෙහෙයුම මඟින් SELECT
එම හැඳුනුම්පත සමඟ පවතින ආයතන සෙවීම සඳහා පසුකාලීන විමසීම් අවුලුවන අතර persist
එම විමසුම් අවශ්ය නොවනු ඇත.
ඩී 4. ඔබේ කේතය අමතන කේතය ඔබ විශ්වාස නොකරන අවස්ථා තිබේ, තවද දත්ත යාවත්කාලීන නොවී ඇතුළු කර ඇති බවට වග බලා ගැනීම සඳහා ඔබ භාවිතා කළ යුතුය persist
.
සැසිවාරයේ තිබූ කම්මැලි පටවන ලද එකතුවකට ප්රවේශ වීමට මා උත්සාහ කළ නිසා මගේ ආයතනයට කම්මැලි පැටවුම් ව්යතිරේකයන් ලැබුණි.
මා කළ යුත්තේ වෙනම ඉල්ලීමකි, සැසියෙන් එම ආයතනය ලබාගෙන ගැටළු සහගත වූ මගේ jsp පිටුවේ එකතුවකට ප්රවේශ වීමට උත්සාහ කරන්න.
මෙය සමනය කිරීම සඳහා, මම මගේ පාලකයේ ඇති එකම ආයතනය යාවත්කාලීන කර එය මගේ jsp වෙත ලබා දුන්නෙමි, නමුත් මම සැසිවාරයේදී නැවත සුරකින විට එය ප්රවේශ විය හැකි නමුත් 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/reference/en/html/objectstate.html
JPA යනු ජාවා වේදිකාව මත ගොඩනගා ඇති ව්යවසාය යෙදුම්වල වසමෙහි විශාල සරල කිරීමකි. J2EE හි පැරණි ආයතන බෝංචි වල සංකීර්ණතාවයන් සමඟ කටයුතු කිරීමට සිදු වූ සංවර්ධකයෙකු ලෙස, ජාවා ඊඊ පිරිවිතරයන් අතර JPA ඇතුළත් කිරීම විශාල ඉදිරි පිම්මක් ලෙස මම දකිමි. කෙසේ වෙතත්, JPA තොරතුරු ගැඹුරින් සොයා බැලීමේදී මට එතරම් පහසු නොවන දේවල් හමු වේ. මෙම ලිපියෙන් මම එන්ටිටි මැනේජර්ගේ ඒකාබද්ධ කිරීම හා අඛණ්ඩව පවතින ක්රම සංසන්දනය කිරීම සමඟ කටයුතු කරමි. ඒවායේ අතිච්ඡාදනය වන හැසිරීම නවකයකුට පමණක් නොව ව්යාකූලත්වයට හේතු විය හැකිය. තව දුරටත් මම යෝජනා කරන්නේ ක්රම දෙකම වඩාත් සාමාන්ය ක්රමවේදයක විශේෂ අවස්ථා ලෙස දකින සාමාන්යකරණයකි.
නොනැසී පවතින ආයතන
ඒකාබද්ධ කිරීමේ ක්රමයට හාත්පසින්ම වෙනස්ව පවතින ක්රමය ඉතා සරල හා බුද්ධිමත් ය. නොනැසී පවත්නා ක්රමයේ භාවිතයේ වඩාත් පොදු අවස්ථාව පහත පරිදි සාරාංශ කළ හැකිය:
"වස්තු පන්තියේ අළුතින් සාදන ලද අවස්ථාවක් අඛණ්ඩ ක්රමයට යවනු ලැබේ. මෙම ක්රමය නැවත පැමිණීමෙන් පසු, එම ආයතනය කළමනාකරණය කර දත්ත සමුදායට ඇතුළු කිරීමට සැලසුම් කර ඇත. එය සිදු වන්නේ ගනුදෙනුව සිදු වීමට පෙර හෝ ෆ්ලෂ් ක්රමය හැඳින්වූ විටය. PERSIST කඳුරැල්ල උපාය මාර්ගයෙන් සලකුණු කරන ලද සම්බන්ධතාවයක් හරහා ආයතනය වෙනත් ආයතනයක් ගැන සඳහන් කරන්නේ නම්, මෙම ක්රියා පටිපාටිය ද එයට අදාළ වේ.
පිරිවිතරයන් වැඩි විස්තර වලට යොමු වේ, කෙසේ වෙතත්, මෙම තොරතුරු වැඩි වශයෙන් හෝ අඩු විදේශීය අවස්ථා පමණක් ආවරණය වන බැවින් ඒවා මතක තබා ගැනීම ඉතා වැදගත් නොවේ.
ආයතන ඒකාබද්ධ කිරීම
නොනැසී පැවතීමට සාපේක්ෂව, ඒකාබද්ධයේ හැසිරීම පිළිබඳ විස්තරය එතරම් සරල නැත. නොනැසී පවතින ආකාරයටම ප්රධාන දර්ශනයක් නොමැත, නිවැරදි කේතයක් ලිවීම සඳහා ක්රමලේඛකයෙකු සියලු අවස්ථා මතක තබා ගත යුතුය. ජේපීඒ නිර්මාණකරුවන්ට අවශ්ය වී ඇත්තේ වෙන්වූ ආයතන හැසිරවීමේ මූලික අවධානය යොමු කළ යුතු ක්රමවේදයක් ඇති බව මට පෙනේ (අළුතින් නිර්මාණය කරන ලද ආයතන සමඟ කටයුතු කරන අඛණ්ඩ ක්රමයට ප්රතිවිරුද්ධ ලෙස.) ඒකාබද්ධ කිරීමේ ක්රමයේ ප්රධාන කාර්යය වන්නේ රාජ්යය මාරු කිරීම කළමනාකරණය නොකළ වස්තුව (තර්කය ලෙස සම්මත) අඛණ්ඩ සන්දර්භය තුළ එහි කළමනාකරණ සහකරුට. කෙසේ වෙතත්, මෙම කර්තව්යය සමස්ත ක්රමයේ හැසිරීමේ බුද්ධිය නරක අතට හැරෙන අවස්ථා කිහිපයකට තවදුරටත් බෙදී යයි.
JPA පිරිවිතරයෙන් ඡේද පුනරාවර්තනය කරනවා වෙනුවට, ඒකාබද්ධ කිරීමේ ක්රමයේ හැසිරීම ක්රමානුකූලව නිරූපණය කරන ප්රවාහ රූප සටහනක් මම සකස් කර ඇත්තෙමි.
ඉතින්, මම දිගටම භාවිතා කළ යුත්තේ කවදාද?
නොනැසී පවතිනවා
ඒකාබද්ධ කරන්න
පිළිතුරු සොයා බැලීමේදී 'කැස්කේඩ්' සහ හැඳුනුම්පත් උත්පාදනය පිළිබඳ විස්තර කිහිපයක් නොමැත. ප්රශ්නය බලන්න
එසේම, Cascade
ඒකාබද්ධ කිරීම හා නොනැසී පැවතීම සඳහා ඔබට වෙනම විවරණ ලබා ගත හැකි බව සඳහන් කිරීම වටී : Cascade.MERGE
ඒවා Cascade.PERSIST
භාවිතා කළ ක්රමයට අනුව සලකනු ලැබේ.
පිරිවිතර ඔබේ මිතුරා ය;)
සිදුවීම X:
වගුව: ස්පිටර් (එකක්), වගුව: ස්පිට්ල්ස් (බොහෝ) (ස්පිට්ල්ස් යනු එෆ්කේ සමඟ සම්බන්ධතාවයේ හිමිකරු ය: ස්පිටර්_අයිඩී)
මෙම තත්වය සුරැකීමට හේතු වේ: ස්පිටර් සහ ස්පිට්ල්ස් දෙකම එකම ස්පිටර් සතු ය.
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!!
සිදුවීම Y:
මෙය ස්පිටර් සුරකිනු ඇත, ස්පිට්ල්ස් 2 සුරකිනු ඇත, නමුත් ඔවුන් එකම ස්පිටර් ගැන සඳහන් නොකරයි!
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.PersistentObjectException: නොනැසී පැවතීම
hibernate-jpa javadoc හි ඉඟියක් ඇත:
අවුලට පත් : javax.persistence.EntityExistsException - ස්ංකීර්ණ දැනටමත් පවතී නම්. .
persist()
එයට හැඳුනුම්පතක් ඇති බවට පැමිණිලි නොකරනු ඇත, එය පැමිණිලි කරන්නේ එකම හැඳුනුම්පතක් ඇති යමක් දැනටමත් දත්ත ගබඩාවේ ඇති විට පමණි.
නොපසුබටව භාවිතා කළ යුත්තේ කවදාද සහ ඒකාබද්ධ කිරීම භාවිතා කළ යුත්තේ කවදාද යන්න පිළිබඳ උපදෙස් සඳහා ඔබ මෙහි පැමිණ ඇත . එය තත්වය මත රඳා පවතී යැයි මම සිතමි: ඔබට නව වාර්තාවක් සෑදීමට අවශ්ය වන්නේ කෙසේද සහ අඛණ්ඩ දත්ත ලබා ගැනීම කෙතරම් දුෂ්කර ද?
ඔබට ස්වාභාවික යතුරක් / හඳුනාගැනීමක් භාවිතා කළ හැකි යැයි සිතමු.
දත්ත අඛණ්ඩව පැවතිය යුතුය, නමුත් වරකට වරක් වාර්තාවක් පවතින අතර යාවත්කාලීන කිරීමක් ඉල්ලා සිටී. මෙම අවස්ථාවේදී ඔබට දිගටම උත්සාහ කළ හැකි අතර එය EntityExistsException එකක් විසි කරන්නේ නම්, ඔබ එය සොයා බලා දත්ත ඒකාබද්ධ කරයි:
උත්සාහ කරන්න {ಅಸ್ತಿತ್ವ කළමනාකරු.පර්සිස්ට් (වස්තුව)}
ඇල්ලීම (EntityExistsException exception) {/ * ලබාගෙන ඒකාබද්ධ කරන්න * /}
නොනැසී පවතින දත්ත යාවත්කාලීන කළ යුතුය, නමුත් වරකට වරක් දත්ත සඳහා තවමත් වාර්තාවක් නොමැත. මෙම අවස්ථාවේදී ඔබ එය සොයා බලා ආයතනය අස්ථානගත වී ඇත්නම් දිගටම කරගෙන යන්න:
ಅಸ್ತಿತ್ವ = ಅಸ್ತಿತ್ವ කළමනාකරු.ෆයින්ඩ් (යතුර);
if (ಅಸ್ತಿತ್ವ == ශූන්ය) {ಅಸ್ತಿತ್ವ කළමනාකරු.පර්සිස්ට් (වස්තුව); }
වෙනත් {/ * ඒකාබද්ධ කිරීම * /}
ඔබට ස්වාභාවික යතුරු / හඳුනාගැනීමක් නොමැති නම්, එම ආයතනය පවතින්නේද නැද්ද යන්න සොයා ගැනීමට ඔබට අපහසු කාලයක් තිබේ, නැතහොත් එය සොයා ගන්නේ කෙසේද.
ඒකාබද්ධ කිරීම් දෙයාකාරයකින් ද විසඳිය හැකිය:
නොනැසී පැවතීම (වස්තුව) මුළුමනින්ම නව ආයතන සමඟ භාවිතා කළ යුතුය, ඒවා ඩී.බී. වෙත එක් කිරීම සඳහා (ඩී.බී. තුළ දැනටමත් වස්තුවක් තිබේ නම් එන්ටිටිඑක්සිස්ට්එක්සෙෂන් විසිකිරීමක් ඇත).
ඒකාබද්ධ කිරීම (වස්තුව) භාවිතා කළ යුතු අතර, එම ආයතනය වෙන් කොට වෙනස් කරන ලද්දේ නම්, එය අඛණ්ඩව පවතින සන්දර්භයට ගෙන ඒමට.
INSERT sql ප්රකාශයක් ජනනය කිරීම සහ UPDATE sql ප්රකාශය ඒකාබද්ධ කිරීම බොහෝ විට නොනැසී පවතී (නමුත් මට විශ්වාස නැත).