حذف یک موجودیت و وابستگی‌هایش به صورت سلسله مراتبی در فریم ورک اسپرینگ(Spring Framework)

۲۱ دی ۱۳۹۵

پیش از هر چیز باید بگویم که این نوشته مربوط به برنامه‌نویسی در فریم‌ورک اسپرینگ و هایبرنیت است؛ اگر با این فریم‌ورک آشنایی ندارید، خواندن این نوشته‌ی من در مورد این چهارچوب برنامه‌نویسی می‌تواند برای شما مفید باشد. هایبرنیت یک کتابخانه object-relational mapping برای زبان جاوا است که چارچوبی را برای نگاشتت یک شی به یک پایگاه داده رابطه‌ای فراهم می‌آورد. فرض کنید سه مدل که به صورت سلسله مراتبی و چند سطحی به هم وابستگی دارند؛ به عنوان مثال یک مدل تحت عنوان survey داریم که یک set از مدل question دارد که این مدل هم یک set از مدل option دارد.



قطعه xml زیر، نحوه وابستگی مدل survey به مدل question را نشان می‌دهد. فایل‌های hbm برای سایر مدل‌ها نیز مشابه قطعه کد زیر است.


<set name="questions">
   <key>
      <column name="survey_id" not-null="true" />
   </key>
   <one-to-many class="org.somePackages.SurveyQuestion" />
</set>

در این حالت اگر بخواهیم یک Instance از مدل سطح اول یا همان survey را حذف نماییم بایستی "cascade="delete؛ را به تگ set در فایل hbm مدل مربوطه اضافه کنیم. به صورت منطقی باید این آبجکت و تمامی وابستگی‌های آن حذف شوند؛ اما در عمل این اتفاق نخواهد افتاد و با پیام خطا مواجه خواهیم شد؛ دلیل این خطا هم این است که هایبرنت ابتدا می‌خواهد object مورد نظر را از survey حذف کند و از آنجایی که id این  object در جداول دیگر نیز ذخیره شده است، به خطای Cannot delete or update a parent row: a foreign key constraint fails برخواهیم خورد.

برای رفع این مشکل باید در فیلد set در فایل هایبرنت هر مدل عبارت "inverse="true را قرار دهیم؛ استفاده از این property بدین معنی است که مالک رابطه چه طرفی باشد؛ برای مثال قطعه کد زیر را در نظر بگیرید:


<set name="questions" inverse="true" cascade="delete">
   <key>
      <column name="survey_id" not-null="true" />
   </key>
   <one-to-many class="org.somePackages.SurveyQuestion" />
</set>

با اضافه کردن "inverse="true درواقع به هایبرنت می‌گوییم که question مالک رابطه است و survey رابطه را آپدیت نخواهد کرد. با استفاده از این روش وقتی می‌خواهیم مدل سطح اول یا همان survey را حذف نماییم، هایبرنت ابتدا ه سراغ آخرین سطح وابستگی رفته ابتدا objectهای وابسته‌ی آن مدل حذف می‌کند و به همین ترتیب به صورت سلسله مراتبی پیش می‌رود تا به سطح اول (مدل survey) برسد و آن Instance را نیز حذف کند.

هیچ نظری موجود نیست: