كائنات ذاكرة التخزين المؤقت من المستوى الثاني من Hibernate كسول = خطأ ، تؤدي إلى جلب افتراضي = انضمام ، هل تم توثيقه في أي مكان؟

StackOverflow https://stackoverflow.com/questions/1968767

سؤال

لقد واجهت القضية التالية غير الموثقة على ما يبدو ، وأريد أن أفهم إذا

  1. لقد فعلت شيئا خاطئا
  2. هل واجه أي شخص نفس القضية؟
  3. هل هو حقا غير موثق في أي مكان؟ أو هل فاتني شيء؟

السلوك هو أن هذا يفترض التعيين التالي

<class name="org.sample.Foo" table="foo">
    ...
   <many-to-one name="bar" class="org.sample.Bar"/>
</class>


<class name="org.sample.Bar" table="bar" lazy="false">
    ...
</class>

أولاً ، كخلفية ، القيمة الافتراضية لـ Hibernate لـ أحضر يجب أن تكون السمة على علاقة كثيرة "تحديد"، هذا على الأقل ما هو موثق (سأضيف الرابط هنا عندما أجده)

ومع ذلك ، يبدو أن هذا صحيح فقط إذا كانت الفئة المرجعية كسول = "صحيح"!

لذلك يبدو أن رسم الخرائط أعلاه تترجم إلى هذا (لأن الشريط كسول = "خطأ"):

<class name="org.sample.Foo" table="foo">
    ...
   <many-to-one name="bar" class="org.sample.Bar" *fetch="join" />
</class>


<class name="org.sample.Bar" table="bar" lazy="false">
    ...
</class>

الآن لماذا ستكون هذه مشكلة؟ بدلاً من تحديد 2 ، ستقوم Hibernate بتحميل المرجع غير الكسول في مجموعة مختارة واحدة مع "الأصل" (تحميل Foo مع شريط في اختيار واحد)

هذا منطقي في الواقع ، لأن الكائن ليس كسولًا ، لماذا لا يتم تحميله؟

الجواب هذا: ماذا يحدث إذا كان بار في ذاكرة التخزين المؤقت من المستوى الثاني؟

<class name="org.sample.Foo" table="foo">
    ...
   <many-to-one name="bar" class="org.sample.Bar" *fetch="join" />
</class>


<class name="org.sample.Bar" table="bar" lazy="false">
    <cache usage="transactional" />
    ...
</class>

والإجابة على ذلك - لا شيء يتغير!

من الواضح أن المرء يفترض أن السبات ذكي بما يكفي لفهم أنه لا ينبغي تحميل الكائنات من هذا النوع ، ولكن نظرًا لأن الجلب الافتراضي قد تم تغييره من SELECT إلى الانضمام ، فإن Hibernate ليس لديه خيار (لا يمكنك الانضمام إلى جدول حقيقي مع ذاكرة التخزين المؤقت من المستوى الثاني ، حتى الآن)

لذا فإن السبات يفعل ما يقال له ، ويستخدم صلة لجلب كائن من قاعدة البيانات حيث يوجد بالفعل في ذاكرة التخزين المؤقت للمستوى الثاني

الحل الذي وجدته هو تغيير التعيين حرفيًا لجلب = "حدد"

الآن عندما يكون الاختيار الثاني لـ BAR على وشك الذهاب ، يفهم Hibernate أنه يجب ألا يذهب إلى قاعدة البيانات ، ويحضرها من ذاكرة التخزين المؤقت. وسيتم تنفيذ استعلام واحد فقط (بعد الاحماء)

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

المحلول

لقد واجهت نفس المشكلة ، ووجدت نفسي أحدد جميع العلاقات التي سيتم تخزينها مؤقتًا fetch="select". في الوقت الذي يتم فيه بناء الاستعلام ، لا يمكن لـ Hibernate معرفة ما إذا كان مثيل الشريط المطلوب في ذاكرة التخزين المؤقت من المستوى الثاني أم لا (على افتراض أن FOO ليس في المخزونات).

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