سؤال

إذا كان لديك كيان a مع تعيين واحد ثنائي الاتجاه واحد أو صفر إلى واحد مع كيان B.

التعيين هو كما يلي:

<class name="EntityA" table="TABLE_A" mutable="true" lazy="true">
    <id name="idA" type="long" column="pk_a" unsaved-value="null">
        <generator class="sequence">
            <param name="sequence">pk_a_seq</param>
        </generator>
    </id>
    <one-to-one name="propertyB" class="EntityB" property-ref="propertyA" constrained="true" outer-join="false"/>
</class>

و

<class name="EntityB" table="TABLE_B" mutable="true" lazy="true">
    <id name="idB" type="long" column="pk_b" unsaved-value="null">
        <generator class="sequence">
            <param name="sequence">pk_b_seq</param>
        </generator>
    </id>
    <many-to-one name="propertyA" class="EntityA" not-null="true" unique="true" lazy="proxy" column="fk_a"/>
</class>

عندما أقوم بإجراء استعلام HQL (أو بالأحرى، استعلام محركات HQL المسمى) لل Entitya، Libernate Finegly Loads Entitya # VeryberB مع عبارة SELECT منفصلة.

مشكلتي في ذلك إذا عودت HQL الخاصة بي 1000 Entitya (مع وجود كل من EntiteB's) الخاص بها)، فإن السبات سيفعل الاستعلامات N + 1 (سيكون الاستعلام الأول من أجل Entitya إرجاع 1000 نتيجة، في حين أن استفسارات N ستأتي من Entitya # peryperb حدد lazy loading).

ومع ذلك، لا أحتاج إلى هذه الخصائص Entitya # لهذا السبب أريد حملها كسول بدلا من ذلك (دون استخدام السبات استعلام منفصل SQL).

هل هذا ممكن؟ وإذا كان كذلك، كيف أفعل ذلك؟

شكرا، فرانز

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

المحلول

لقد إصلاح هذه المشكلة.

ما فعلته هو إنشاء إيقاف تشغيل Entitya # Veryber في مجموعة مع اسم Entitya # الخاصية. لكنني احتفظت ب Orditya # GetPropertyb () و ENTITYA # SETPROPERTYB (EntityB Veryperb) طرق Accessor.

هيئات طرق تلك طرق الملحقات هي الآن شيء مثل هذا:

public EntityB getPropertyB() {
    return CollectionUtils.get(propertyBs, 0);
}

public void setPropertyBs(EntityB propertyB) {
    propertyBs= Collections.singleton(propertyB);
}

ثم في رسم الخرائط الخاصة بي، قمت بتعيين "مجموعة Entitya #" وتحديد الوصول إلى "الحقل".

<set name="scheduledAdInfos" lazy="true" fetch="subselect" access="field" cascade="none" inverse="true">
    <key column="pk_a"/>
    <one-to-many class="EntityB"/>
</set>

باستخدام هذا الإعداد، يمكنك الآن إنشاء رسم خرائط كسول من POJO (ENTITYA) إلى POJO (EntityB) المملوكة حتى إذا كان الجدول_A مملوكة من قبل Table_B.

نصائح أخرى

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


إجابة أطول: يمكن أن تسطب السبات جمعيات الحمولة كسول. الطريقة التي يقوم بها هذا عن طريق حقن كائن وكيل يحمل معرف الكائن المشار إليه.

في قضيتك، فإن التعيين هو بحيث يكون عمود المفتاح الأجنبي في Table_B، أي حيث تستخدم التعيين العديد من إلى One. لذلك إذا قمت بتحميل B، فاكتشف السبات مرجع FK في عمود FK_A ويمكنه إنشاء وكيل يحمل هذه القيمة. عند الوصول إلى الوكيل يتم تحميل الكيان المقابل.

ماذا لو تم تحديد سجل من الجدول A؟ سيقوم HiKenate بإنشاء كائن، ولكن لتتمكن من ملء الخصائص، سيتعين عليك النظر في الجدول_B، للعثور على الصف المقابل مع FK_A = A.ID. لا توجد طريقة أخرى للسبات لمعرفة سجل التحميل في وقت التحميل الكسول.

في الواقع، سيكون هذا تحسنا في السبات، لأنه يجب أن يكون قادرا أيضا على القيام بالتحميل على مفاتيح فريدة أخرى أثناء التحميل الكسول، ولكن التنفيذ الحالي لا يسمح بذلك، ربما يمكنك رفع مشكلة.

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