لماذا يتم العثور على كائن من قبل ID في JPA ، ولكن ليس من خلال استعلام JPQL؟
سؤال
لدي حالة اختبار Junit 4 مع الربيع @Transactional
التعليق التوضيحي الذي يحفظ كائن ، ثم يحاول العثور عليه. تمر حالة الاختبار عندما أستخدم هذا التنفيذ:
@Override
public EventSummary findEventSummaryById(Integer id) {
return em.find(EventSummary.class, id);
}
يفشل عند استخدام هذا التنفيذ (ثم تغيير الطريقة التي أسميها في حالة الاختبار):
@Override
public EventSummary findEventSummary(Integer id) {
Query query = em.createQuery("select es from EventSummary as es where es.id = :id");
query.setParameter("id", id);
EventSummary result = (EventSummary) query.getSingleResult();
return result;
}
المحلول
إذا كنت تستخدم وضع التدفق الافتراضي (AUTO
) وإذا كنت تقوم بتنفيذ استعلامك ضمن معاملة ، فإن مواصفات JPA يضمن أن الاستعلام لن يعيد بيانات قديمة أو غير صحيحة:
3.6.2 استفسارات و flushmode
يؤثر إعداد وضع التدفق على نتيجة الاستعلام على النحو التالي.
عندما يتم تنفيذ الاستعلامات داخل معاملة ، إذا
FlushModeType.AUTO
تم تعيينه علىQuery
الكائن ، أو إذا كان إعداد وضع التدفق لسياق الثبات هوAUTO
(الافتراضي) وإعداد وضع التدفق لم يتم تحديده لQuery
كائن ، يكون مزود الثبات مسؤولاً عن ضمان أن جميع التحديثات إلى حالة جميع الكيانات في سياق الثبات والتي يمكن أن تؤثر على نتيجة الاستعلام مرئية لمعالجة الاستعلام. قد يحقق تنفيذ مزود الثبات هذا عن طريق مسح تلك الكيانات إلى قاعدة البيانات أو بوسائل أخرى. لوFlushModeType.COMMIT
تم تعيينه ، تأثير التحديثات التي تم إجراؤها على الكيانات في سياق الثبات عند الاستعلامات غير محدد.public enum FlushModeType { COMMIT, AUTO }
إذا لم يكن هناك معاملة نشطة ، يجب ألا يتدفق مزود الثبات إلى قاعدة البيانات.
على افتراض أنك تستخدم AUTO
, ، تحقق من الجانب المعاملات.
نصائح أخرى
كيان في الجلسة الحالية (مدير الكيان) - إنه في حالة مستمرة ، في انتظار أن يتم مسحها. تتحقق طريقة GET أولاً من محتويات الجلسة ، وإذا لم يتم العثور عليها تتحول إلى قاعدة البيانات الأساسية. في حالتك ، تم حفظ الكيان للتو في الجلسة نفسها ، لذلك تم العثور عليه وإعادته.
تحديث: اتضح أن المشكلة هي استخدام مدير معاملات غير صحيح ، وبالتالي لم يتم مسح الكيان إلى قاعدة البيانات. انظر تفسير باسكال.
في الحالة الأولى ، المعرف هو عدد صحيح
في الثانية ، المعرف هو سلسلة
عدد صحيح لن يساوي سلسلة أبدا