سؤال

يبدو كيان المفتاح الأساسي الخاص بي كما هو موضح أدناه

@GeneratedValue(strategy= GenerationType.TABLE)
private Long id;

عندما أركض، أحصل على خطأ

تعذر الحصول على القيمة التالية أو تحديثها؛ الاستثناء المتداخل هو org.hibernate.exception.SQLGrammerException: تعذر الحصول على القيمة التالية أو تحديثها

ولكن عندما أقوم بالتغيير إلى

@GeneratedValue 
private Long id;

لا يوجد خطأ رمي.أريد إنشاء مفتاح أساسي فريد لكل جدول وحي ديسيبل.

هل كانت مفيدة؟

المحلول

ال @GeneratedValue(strategy=GenerationType.TABLE) يخبر موفر JPA باستخدام جدول للحصول على المعرفات منه عند إدراج الكيانات المنشأة حديثًا في قاعدة البيانات.

عند استخدام السبات كموفر، سيؤدي ذلك إلى جدول hibernate_sequences والذي يحتوي على عمودين:اسم الكيان والحد الأقصى للهوية المعينة بالفعل لهذا الكيان.هنا، يبدو أن Hibernate لم ينجح في الحصول على المعرف التالي للكيان الخاص بك ولكن من الصعب تحديد السبب بالضبط لأنك لم تقدم معلومات كافية لذلك.

لذا، هل يمكنك تقديم تتبع المكدس الكامل؟أيضا، يرجى تحويل التسجيل مع hibernate.show_sql خاصية تعيين ل true وتعيين مستوى السجل المناسب log4j.logger.org.hibernate.SQL=DEBUG.انضم إلى السجل الخاص بسؤالك إن أمكن.

ربما فقط تأكد من أنك قمت بتكوين الصحيح hibernate.dialect لأوراكل.في الواقع، انضم إلى تكوين السبات الخاص بك أيضًا إن أمكن.

ملاحظة:تتمثل الطريقة "التقليدية" لإنشاء PK باستخدام Oracle في استخدام التسلسلات (يمكنك السماح لـ Hibernate بتخمين أفضل استراتيجية لنوع قاعدة البيانات الخاصة بك باستخدام GenerationType.AUTO أو إجباره على الاستخدام SEQUENCE) لكنني سأفترض أنك تريد أن تكون بنية البيانات الناتجة ملحة لقاعدة البيانات.إذا لم يكن الأمر كذلك، فأنا أقترح الذهاب للتسلسلات بدلاً من ذلك.

يحرر:الرد على تعليق من OP حول GenerationType.AUTO.في الواقع، الافتراضي هو تسلسل عالمي واحد يسمى hibernate_sequence وقد تكون هذه مشكلة.ولكن، مع الإعداد الموضح أدناه، يمكنك استخدامه GenerationType.AUTO وما زال يتحكم في اسم التسلسل للحالات التي تستخدم فيها قاعدة البيانات التسلسلات:

@Id
@GeneratedValue(strategy=GenerationType.AUTO, generator="my_entity_seq_gen")
@SequenceGenerator(name="my_entity_seq_gen", sequenceName="MY_ENTITY_SEQ")
private long id;

بمعنى آخر، يمكنك استخدام اسم تسلسل مختلف لكل جدول دون فقدان إمكانية النقل.

نصائح أخرى

هناك 4 استراتيجيات لتوليد السيارات في JPA:

  • آلي
  • هوية
  • تسلسل
  • طاولة

بالنسبة للتعليق التوضيحي للمفتاح الأساسي للتوليد التلقائي لـ Oracle، فإن التسلسل والجدول هي اختياراتك.المنطق الأساسي هو تحديد المولد أولاً واستخدامه @SequenceGenerator أو @TableGenerator على التوالي، ثم استخدم المولد كسمة في @القيمة المولدة.

هذه عينة لكيفية استخدام استراتيجية التسلسل:

  @Id
  @SequenceGenerator(name="SEQ_GEN", sequenceName="SEQ_JUST_FOR_TEST", allocationSize=1)
  @GeneratedValue(strategy=GenerationType.SEQUENCE, generator="SEQ_GEN")
  private long id;

فيما يلي مثال لكيفية استخدام استراتيجية الجدول:

  @Id
  @TableGenerator(name="TABLE_GEN",table="T_GENERATOR", pkColumnName = "GEN_KEY", pkColumnValue = "MONITOR2012.T_JUST_FOR_TEST", valueColumnName = "GEN_VALUE", initialValue = 1, allocationSize = 1 )
  @GeneratedValue(strategy = GenerationType.TABLE, generator="TABLE_GEN")
  private long id;

إذا لم يتم تحديد مولد في @القيمة المولدة تعليق توضيحي، سيترك الاختيار لتنفيذ JPA.

إذا كنت تعمل على قاعدة بيانات تحتوي على جداول موجودة، فتأكد من التسلسل أو الجدول المحدد في قاعدة البيانات قبل تشغيل التطبيق الخاص بك. سيحتاج منشئ الجدول أيضًا إلى إدراج سطر في الجدول قبل أن يعمل التعليق التوضيحي @GeneratedValue بشكل صحيح.

هنا برنامج تعليمي حول كيفية تكوين الإنشاء التلقائي للمفتاح الأساسي في JPA لقاعدة بيانات Oracle.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top