استفاده از تگ List در فایل هایبرنت (پیکربندی XML)

پیش از هر چیز باید بگویم که این نوشته مربوط به برنامه‌نویسی در فریم‌ورک اسپرینگ و هایبرنیت است؛ اگر با این فریم‌ورک آشنایی ندارید، خواندن این نوشته‌ی من در مورد این چهارچوب برنامه‌نویسی می‌تواند برای شما مفید باشد. هایبرنیت یک کتابخانه object-relational mapping برای زبان جاوا است که چارچوبی را برای نگاشت یک شی به یک پایگاه داده رابطه‌ای فراهم می‌آورد. فرض کنید مدلی به نام سوالات (Question) داریم که شامل دو یا چند گزینه بوده و ارتباطی یک به چند با مدل گزینه‌ها (Option) دارد؛ باتوجه به اینکه ترتیب گزینه‌های سوال برای ما مهم است و می‌خواهیم هایبرنت به صورت خودکار ترتیب گزینه‌ها را برای ما حفظ کند.

بنابراین از نوع داده‌ای java.util.List استفاده می‌کنیم. مدل و فایل hbm سوالات به صورت زیر است:

public class Question extends BaseEntity<Long> {  
  private String             title;  
  private List<Option>options;  
  //other properties and getters & getters  
}
<hibernate-mapping>  
  <class  name="org.packages.Question"  table="Question"  >  
    <property name="title"     column="title"       type="string"not-null="false" />  
    <!\-\- other properties -->  
    <list name="options" cascade="all" inverse="true" >  
      <key>  
        <column name="question_id" not-null="true" />  
      </key>  
      <list-index column="idx" base="0" />  
      <one-to-many class="org.packages.Option" />  
    </list>  
  </class>  
</hibernate-mapping>

در تگ list فایل hbm تقریبا بسیاری از propertyها با تگ set (که پرکاربردتر است) یکی هستند، تگ list-index یک تگ الزامی برای حفظ ترتیب‌ها در پایگاه داده در تگ list است و شامل دو property با نامهای column و base است. column برای نام ستون ترتیب عناصر لیست است و اگر هم نامی برای ستون list-index در نظر نگیریم خود هایبرنت نام idx را به این ستون خواهد داد. همچنین base عدد order یا ترتیب عناصر لیست ذخیره شده در پایگاه داده را مشخص می‌کند. درنهایت ذکر این نکته ضروری است که مدیریت list-index کاملا توسط هایبرنت انجام می‌شود.

اما مشکلی که در کار با list رخ می‌دهد مربوط به زمان آپدیت‌کردن رکوردهاست؛ در درج عناصر جدید که در اینجا گزینه‌های ما (مدل option) هستند ترتیب گزینه‌ها (idx) به صورت درست بوده و برای گزینه اول عدد ۰، برای گزینه دوم عدد ۱ و گزینه سوم عدد ۲ است. اما وقتی که می‌خواهیم گزینه‌های سوال را آپدیت کنیم این ترتیب تغییر می‌کند؛ برای ترتیب جدید، هایبرنت ابتدا ماکزیمم ستون idx را محاسبه کرده و سپس این مقدار ماکزیمم بعلاوه یک را برای ترتیب گزینه ها در نظر می‌گیرد، به عنوان مثال برای گزینه اول عدد ۳، برای گزینه دوم عدد ۴ و گزینه سوم عدد ۵ ترتیب‌های جدید می‌شوند، حال اگر jackson بخواهد خروجی json سوال و گزینه‌های آن را تولید کند، چون در لیست ترتیب عناصر مهم است، در لیست گزینه‌ها ترتیب گزینه اول را عدد ۳ می‌خواند و نتیجه می‌گیرد که گزینه اول موقعیت سوم در لیست گزینه‌ها را دارد، به این ترتیب سه مقدار null در لیست json خروجی قبل از گزینه اول قرار می‌دهد. هر بار که گزینه‌های سوال را آپدیت کنیم ترتیب گزینه‌ها idx بیشتر شده و تعداد عناصر null در لیست json خروجی ما بیشتر خواهند شد.

برای حل این مشکل دو راه‌حل وجود دارد؛ راه‌حل اول استفاده از set به جای List و کنترل دستی ترتیب عناصر با استفاده از یک property مثل sequence است. راه‌حل دوم نیز پاک کردن تمامی گزینه‌های یک سوال و درج مجدد آنهاست که در این صورت ترتیب گزینه‌ها درست خواهد بود و عنصر nullی در لیست json خروجی خود نیز نخواهیم داشت؛ البته چون در این حالت هایبرنت ترتیب عناصر را به جای ۰ از ۱ شروع می‌کند، لذا بایستی در این حالتbase مربوط به ستون list-index را به جای ۰ برابر با مقدار ۱ قرار داد.


برچسب‌ها:،،،،،،
مرتضی اسدی
مرتضی اسدی
سلام! من مرتضی اسدی هستم، یک توسعه‌دهنده‌ی نرم‌افزار و در این وبلاگ دست‌نوشته‌هایم را می‌نویسم.