GeneratedValue in JPA | GeneratedValue در JPA
📖توضیحات درس
📄جزوه
مفاهیم کلیدی
-
@GeneratedValueانوتیشنی در JPA که برای تعیین استراتژی تولید خودکار مقادیر برای فیلدهای کلید اصلی (Primary Key) استفاده میشود. این انوتیشن به برنامهنویس اجازه میدهد بدون درگیر شدن با مدیریت دستی آیدیها، تولید مقادیر یونیک را به دیتابیس یا JPA Provider بسپارد. -
GenerationType.IDENTITYاستراتژی تولید کلید اصلی که بر قابلیتAuto-incrementخود پایگاه داده تکیه دارد. در این حالت، دیتابیس وظیفه دارد پس از انجام عملیاتInsertمقدار آیدی را تولید کند. این روش در دیتابیسهایی مانند MySQL و PostgreSQL (از طریق هویت ستون) پشتیبانی میشود. -
GenerationType.SEQUENCEاستراتژی که از یک شیء جداگانه در پایگاه داده به نامSequenceبرای تولید مقادیر یونیک استفاده میکند. قبل از انجامInsertمقدار بعدی از این شیء گرفته شده و به انتیتی اختصاص مییابد. این روش برای برنامههای با مقیاس بزرگ بسیار بهینه است. -
GenerationType.TABLEروشی که از یک جدول مجزا در دیتابیس برای شبیهسازی Sequence و نگهداری آخرین مقدار تولید شده استفاده میکند. این استراتژی مستقل از نوع دیتابیس است اما به دلیل نیاز به قفلگذاری و کوئریهای اضافه، کارایی (Performance) پایینتری دارد. -
GenerationType.AUTOاستراتژی پیشفرض که در آن JPA Provider (مانند Hibernate) بر اساس نوع پایگاه دادهای که به پروژه متصل است، بهترین استراتژی تولید آیدی را انتخاب میکند. -
Allocation Sizeپارامتری درSequenceGeneratorکه تعیین میکند در هر بار درخواست به دیتابیس، چه تعداد شماره آیدی رزرو شده و در حافظه (Cache) برنامه نگهداری شود. این کار باعث کاهش تعداد مراجعات به دیتابیس و افزایش سرعت میشود.
موارد مصاحبه ای
-
چرا استفاده از
@GeneratedValueضروری است؟ در محیطهای عملیاتی که چندین کاربر به صورت همزمان داده درج میکنند، مدیریت دستی آیدیها منجر به خطایDuplicate Key Valueمیشود. این انوتیشن تضمین میکند که هر رکورد یک کلید اصلی یونیک و ناتنال دریافت کند. -
تفاوت اصلی بین IDENTITY و SEQUENCE چیست؟ در استراتژی
IDENTITYمقدار آیدی بعد از اجرای دستورInsertمشخص میشود، بنابراین Hibernate نمیتواند عملیات درج گروهی (Batch Insert) را به خوبی بهینه کند. اما درSEQUENCEمقدار آیدی قبل از درج از دیتابیس گرفته میشود که اجازه بهینهسازی بهتر را میدهد. -
چرا SEQUENCE برای برنامههای با مقیاس بزرگ (Large Scale) مناسبتر است؟ به دلیل قابلیت
Allocation Size. برنامه میتواند مثلاً ۵۰ عدد آیدی را یکجا از دیتابیس رزرو کند و در حافظه نگه دارد. تا زمانی که این ۵۰ ظرفیت پر نشود، نیازی به ارتباط مجدد با دیتابیس برای گرفتن آیدی جدید نیست که این موضوع فشار روی دیتابیس را به شدت کاهش میدهد. -
کدام استراتژی بیشترین سازگاری را با انواع دیتابیسها دارد؟ استراتژی
TABLE؛ زیرا تمام دیتابیسها از جدول پشتیبانی میکنند. با این حال به دلیلOverheadبالا، تنها زمانی توصیه میشود که دیتابیس ازIdentityیاSequenceپشتیبانی نکند. -
مفهوم
GenerationType.AUTOدر دیتابیس PostgreSQL چگونه عمل میکند؟ در PostgreSQL، هایبرنت به طور هوشمند تشخیص میدهد که این دیتابیس ازSequenceپشتیبانی میکند، بنابراین به طور خودکار استراتژی را رویSEQUENCEتنظیم کرده و یک شیء توالی برای آن میسازد.
سناریو کاربردی
در یک سیستم مدیریت دانشجویان، کلاسی به نام Student تعریف شده است. در ابتدا اگر برنامهنویس بخواهد آیدی هر دانشجو را دستی وارد کند، باید مدام آخرین آیدی موجود در دیتابیس را چک کرده و یکی به آن اضافه کند. این کار در سیستمهای واقعی غیرممکن است.
با قرار دادن @GeneratedValue(strategy = GenerationType.SEQUENCE) روی فیلد آیدی، هایبرنت هنگام اجرای برنامه در PostgreSQL، یک شیء به نام student_table_seq در دیتابیس میسازد. در هر بار ذخیره دانشجو، هایبرنت ابتدا یک کوئری SELECT NEXTVAL میزند، شماره آیدی را دریافت کرده و سپس دانشجو را با آن آیدی ذخیره میکند. اگر Allocation Size روی ۵۰ باشد، هایبرنت یک بار عدد را میگیرد و برای ۵۰ دانشجوی بعدی در حافظه خودش آیدی تولید میکند بدون اینکه دوباره به دیتابیس درخواستی بفرستد.
بیشتر بدانید
-
نکته در مورد
@SequenceGeneratorبرای شخصیسازی نام Sequence در دیتابیس و تنظیمallocationSizeحتماً باید از انوتیشن@SequenceGeneratorدر کنار@GeneratedValueاستفاده کنید و نام آنها را از طریق فیلدgeneratorبه هم متصل کنید. -
نکته در مورد تنظیمات Hibernate برای مشاهده نحوه ساخت جداول و Sequenceها در کنسول، میتوانید در فایل
persistence.xmlخاصیتhibernate.hbm2ddl.autoرا رویcreate-dropقرار دهید تا در هر بار اجرای برنامه، جداول پاک شده و مجدد با ساختار جدید ساخته شوند. -
توسعه با UUID اگر پروژه شما به جای اعداد از رشتههای طولانی و منحصربهفرد جهانی (UUID) استفاده میکند، JPA استراتژی مخصوصی برای تولید خودکار این نوع آیدیها نیز دارد که از طریق
GenerationType.UUIDدر نسخههای جدید در دسترس است.
