سؤال

هل هناك طريقة لتغيير JPA جلب نوع على طريقة واحدة دون تحرير كيان الكائن ؟

أنا مشترك ORM طبقة تتكون من JPA الطبقات الكيان.هذا ORM طبقة الوصول إليها من قبل اثنين داو طبقات.واحد داو يحتاج كسول جلب, كما هو الحال بالنسبة لي تطبيق ويب ، وغيرها من الاحتياجات حريصة على جلب, كما أريد أن threadsafe.

هنا هو مثال على طريقة من threadsafe داو ،

@PersistenceContext(unitName = "PersistenceUnit", type = PersistenceContextType.TRANSACTION)
private EntityManager em;

public ErrorCode findErrorCodeById(short id) {
    return (ErrorCode) em.createNamedQuery("ErrorCode.findById").
            setParameter("id", id).getSingleResult();
}

كيف يمكنني جعل هذا الأسلوب (أو الصف بأكمله) استخدام حريصة متضايقة ؟

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

المحلول

أفترض أن الكيان الجمعيات (@ثنائي, @OneToMany, @ManyToOne) هي fechted كسول (FetchType.كسول)

ثم لا أستطيع التفكير في طريقتين:

A.إرسال اثنين jpa استعلام واحد وهو جلب جمعية كسول (هذا الافتراضي طريقة السبات) و الاستعلام الثاني الذي صريحة القوة حريصة التحميل من جمعية (انظر "جلب" الكلمات الرئيسية في البحث).

        Query q = HibernateUtil.getSessionFactory().getCurrentSession()
                .createQuery("select c from Category as c" +
                        " left join fetch c.categorizedItems as ci" +
                        " join fetch ci.item as i");


ب.استخدام السبات.تهيئة(الكيان) إلى قوة حريصة تحميل كسول العلاقات كيان بعد استرجاعها (مثلا ، من خلال مكتشف ...)

ErrorCode lazyCode = findErrorCodeById(1);
// eager load associations
Hibernate.initialize(lazyCode);

نصائح أخرى

في JPA الجلب وضع المحدد على كل استمرار السمة ، إما عن طريق الشرح أو في xml ملف التعيين.

لذلك JPA بائع الملحد طريقة لتحقيق هدفك هو أن يكون مستقلا ملف تعيين لكل داو طبقة.للأسف هذا يتطلب منفصلة PersistenceUnit لكل ملف التعيين ، ولكن يمكنك على الأقل حصة نفس الطبقات الكيان ونفس JPQL الاستعلام.

رمز الهياكل العظمية متابعة.

persistence.xml :

<persistence>
    <persistence-unit name="dao-eager">
        <mapping-file>orm-eager.xml</mapping-file>
    </persistence-unit>

    <persistence-unit name="dao-lazy">
        <mapping-file>orm-lazy.xml</mapping-file>
    </persistence-unit>
</persistence>

orm-eager.xml :

<entity-mappings>
    <entity class="ErrorCode">
        <attributes>
            <basic name="name" fetch="EAGER"/>
        </attributes>
    </entity> 
</entity-mappings>

orm-lazy.xml :

<entity-mappings>
    <entity class="ErrorCode">
        <attributes>
            <basic name="name" fetch="LAZY"/>
        </attributes>
    </entity> 
</entity-mappings>

ثم انها مجرد مسألة خلق EntityManagerFactory المناسبة استمرار الوحدة في DAO طبقات.

في الواقع لا تحتاج اثنين من الخرائط الملفات ، يمكنك تحديد إما كسول أو حريصة كما في الشرح في الكيان و من ثم تحديد المعاكس في xml ملف تعيين (سوف لا تزال تريد اثنين استمرار الوحدات على الرغم من).

قد يكون قليلا أكثر من رمز من السبات الحل أعلاه ، ولكن التطبيق الخاص بك يجب أن تكون محمولة أخرى JPA البائعين.

بوصفها جانبا ، OpenJPA يوفر وظائف مماثلة إلى السبات الحل أعلاه باستخدام FetchGroups (مفهوم اقترضت من JDO).

واحد التحذير الأخير, FetchType.كسول هو تلميح في JPA ، قد يقوم مزود تحميل الصفوف بفارغ الصبر إذا لزم الأمر.

تحديث في الطلب.

النظر في كيان مثل هذا :

@Entity 
public class ErrorCode { 
    //  . . . 
    @OneToMany(fetch=FetchType.EAGER)  // default fetch is LAZY for Collections
    private Collection myCollection; 
    // . . .
}

في هذه الحالة سوف لا تزال بحاجة إلى اثنين من استمرار وحدة ، ولكن ستحتاج فقط orm-lazy.xml.لقد غيرت اسم الحقل يعكس سيناريو أكثر واقعية (فقط مجموعات النقط استخدام FetchType.كسول بشكل افتراضي).مما orm-lazy.xml قد تبدو مثل هذا :

<entity-mappings>
    <entity class="ErrorCode">
        <attributes>
            <one-to-many name="myCollection" fetch="LAZY"/>
        </attributes>
    </entity> 
</entity-mappings>

و persistence.xml سوف تبدو مثل هذا :

<persistence>
    <persistence-unit name="dao-eager">
       <!--
          . . .
         -->
    </persistence-unit>

    <persistence-unit name="dao-lazy">
        <!--
           . . . 
          -->
        <mapping-file>orm-lazy.xml</mapping-file>
    </persistence-unit>
</persistence>

لأنه لا أحد ذكر OpenJPA, سوف أضع الإجابة هنا.

في OpenJPA ، سابقا كسول تكوين مجموعات الحقول يمكن بفارغ الصبر تحميلها على النحو التالي

    OpenJPAEntityManager kem = OpenJPAPersistence.cast(em);
    kem.getFetchPlan().addField(Order.class, "products");
    TypedQuery<Order> query = kem.createQuery(yourQuery, Order.class);

المرجع:http://openjpa.apache.org/builds/1.0.3/apache-openjpa-1.0.3/docs/manual/ref_guide_fetch.html

في JPA2 يمكنني استخدام EntityGraphs, مما يسمح لك لتحديد ما الكيانات ذات الصلة كنت ترغب في استرداد:

https://docs.oracle.com/javaee/7/tutorial/persistence-entitygraphs002.htm https://docs.oracle.com/javaee/7/tutorial/persistence-entitygraphs003.htm

يمكنك إنشاء NamedQuery كما فعلت ، يمكنك إرفاق تلميحا مع مفتاح javax.persistence.loadgraph أو javax.persistence.fetchgraph.فإنه سيتم استرداد الكيانات ذات الصلة التي قمت بتعريفها في الرسم البياني.

يمكنك العثور على تفاصيل الفرق بين "loadgraph" و "fetchgraph" هنا: ما هو diffenece بين جلب وتحميل الكيان الرسم البياني JPA ؟

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