لا يستطيع EntityManager.find العثور على الكيان، لكن استخدام Criteria API يمكنه ذلك

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

سؤال

لقد واجهت حالة غريبة إلى حد ما في Java EE 6 حيث تم استخدام JPA EntityManager's find الطريقة مع المعرف الأساسي للكيان تُرجع قيمة فارغة، ولكن استخدام Criteria API لتحديد جميع الكيانات ذات هذا المعرف يعمل بشكل جيد.

هذا هو الكود الذي أستخدمه من أجل find:

// Always returns null, even for records I know for sure are in there.
user = em.find(User.class, userId);

...وهذا هو الكود الذي أستخدمه مع Criteria API:

CriteriaBuilder builder = em.getCriteriaBuilder();
CriteriaQuery<User> criteria = builder.createQuery(User.class);
Root<User> u = criteria.from(User.class);
TypedQuery<User> query = em.createQuery(
    criteria.select(u).where(builder.equal(u.get("id"), userId)));
user = query.getSingleResult();

أي فكرة لماذا find تُرجع فارغة ولكن المعايير تجد المستخدم؟لقد جربت هاتين الطريقتين البديلتين في نفس المكان بالضبط في البرنامج.

فيما يلي الأجزاء ذات الصلة من كيان المستخدم:

@Entity
@Table(name = "USERS")
@Access(AccessType.PROPERTY)
public class User implements Serializable {
    ...
    private Long id;
    ...
    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "user_id_generator")
    @SequenceGenerator(name = "user_id_generator", sequenceName = "user_sequence", allocationSize = 1)
    @Column(name="id")
    public Long getId() {
        return this.id;
    }

    public void setId(Long id) {
        this.id = id;
    }
    ...
}
هل كانت مفيدة؟

المحلول

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

نصائح أخرى

ما هو المزود الذي تستخدمه؟

أين يتم تنفيذ هذا الاكتشاف، داخل أو خارج المعاملة؟هل تقوم بمسح ومسح EM قبل الاكتشاف؟

باستخدام EclipseLink كموفر، والنموذج المماثل الخاص بي، لا أستطيع إعادة إنتاج هذا.

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

أؤكد الحل.وحدث الشيء نفسه بالنسبة لي.لقد تم وضع علامة على الأعمدة على أنها NOT NULL, ، ثم أثناء الاختبار في تطبيقي، قمت بإيقاف تشغيل القيد في قاعدة البيانات لعمودين (مفاتيح خارجية)، ولكن لم أغير (optional = false) صفة @ManyToOne العلاقة في فئة الكيان الخاص بي.بعد حذف السمة، بحيث يكون النموذج متوافقًا مع قاعدة البيانات، بدأ كل شيء يعمل بشكل جيد.الغريب أن البيئة لا تنتج تحذيرا أو استثناء من نوع ما.

تأكد من اجتيازك لـ Long في المقتطف التالي:

// Always returns null, even for records I know for sure are in there.
user = em.find(User.class, userId);

إذا لم يساعد ذلك، فقم بتنشيط تسجيل SQL لمعرفة ما يحدث ومقارنة السلوك في كلتا الحالتين.

قد يكون أحد الأسباب هو أن حقل "المعرف" لم يتم وضع علامة عليه بشكل صحيح كمعرف لكيان المستخدم.

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

إذا لم يكن موجودًا في قاعدة البيانات، فتأكد من مسح مدير الكيان أو الالتزام بالمعاملة الحالية.

على سبيل المثال، إذا كنت تستخدم Hibernate كموفر، فمن الممكن أن يكون الكائن "مستمرًا" فقط في ذاكرة التخزين المؤقت ولم يتم دفع التغييرات فعليًا إلى قاعدة البيانات.وفقًا لذلك، فإن المعايير التي تمر عبر تطبيق Hibernate سوف تسترد الكائن، ولكن لن يتمكن مدير الكيان الذي يبحث عنه من تحديد موقع الكائن.

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