spring - بيانات الربيع والاستعلام الأصلي مع ترقيم الصفحات




spring-data spring-data-jpa (7)

في مشروع ويب ، باستخدام أحدث بيانات ربيعية (1.10.2) مع قاعدة بيانات MySQL 5.6 ، أحاول استخدام استعلام أصلي مع ترقيم الصفحات لكنني أواجه org.springframework.data.jpa.repository.query.InvalidJpaQueryMethodException عند بدء التشغيل.

UPDATE : 20180306 تم إصلاح هذه المشكلة الآن في Spring 2.0.4 بالنسبة لأولئك الذين ما زالوا مهتمين أو عالقين مع الإصدارات القديمة ، راجع الإجابات والتعليقات ذات الصلة للحصول على حلول.

وفقًا للمثال 50 عند استخدامQuery من وثائق بيانات الربيع ، من الممكن تحديد الاستعلام نفسه و countQuery ، مثل هذا:

public interface UserRepository extends JpaRepository<User, Long> {
  @Query(value = "SELECT * FROM USERS WHERE LASTNAME = ?1",
    countQuery = "SELECT count(*) FROM USERS WHERE LASTNAME = ?1",
    nativeQuery = true)
  Page<User> findByLastname(String lastname, Pageable pageable);
}

بدافع الفضول ، في فئة NativeJpaQuery أستطيع أن أرى أنه يحتوي على الكود التالي للتحقق مما إذا كان استعلام jpa صالحًا:

public NativeJpaQuery(JpaQueryMethod method, EntityManager em, String queryString, EvaluationContextProvider evaluationContextProvider, SpelExpressionParser parser) {
   super(method, em, queryString, evaluationContextProvider, parser);
   JpaParameters parameters = method.getParameters();
   boolean hasPagingOrSortingParameter = parameters.hasPageableParameter() || parameters.hasSortParameter();
   boolean containsPageableOrSortInQueryExpression = queryString.contains("#pageable") || queryString.contains("#sort");
   if(hasPagingOrSortingParameter && !containsPageableOrSortInQueryExpression) {
       throw new InvalidJpaQueryMethodException("Cannot use native queries with dynamic sorting and/or pagination in method " + method);
   }
}

يحتوي Pageable معلمة Pageable ، لذلك hasPagingOrSortingParameter true ، لكنه يبحث أيضًا عن تسلسل #sort أو #sort داخل queryString ، وهو ما لا queryString .

لقد حاولت إضافة #pageable (إنه تعليق) في نهاية طلب البحث ، مما يجعل التحقق من الصحة يمر ولكن بعد ذلك ، يفشل في التنفيذ ويقول إن الاستعلام يتوقع معلمة إضافية واحدة: 3 بدلاً من 2.

الطريف في الأمر هو أنه إذا قمت يدويًا بتغيير containsPageableOrSortInQueryExpression على queryString من false إلى true أثناء تشغيله ، فإن الاستعلام يعمل بشكل جيد ، لذا لا أعرف سبب التحقق من وجود هذه السلسلة في queryString ولا أعرف كيفية توفيرها.

أي مساعدة سيكون محل تقدير كبير.

تحديث 01/30/2018 يبدو أن المطورين في مشروع البيانات الربيع يعملون على إصلاح لهذه المشكلة مع PR بواسطة Jens Schauder


استبدال / # pageable / بـ؟ # {# pageable} تسمح بإجراء ترقيم الصفحات. تتيح لك إضافة PageableDefault تعيين حجم عناصر الصفحة.


اعتذاري مقدما ، هذا يلخص إلى حد كبير السؤال الأصلي والتعليق من Janar ، ولكن ...

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

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

    @Query(value="SELECT a.* "
            + "FROM author a left outer join mappable_natural_person p on a.id = p.provenance_id "
            + "WHERE p.update_time is null OR (p.provenance_name='biblio_db' and a.update_time>p.update_time)"
            + "ORDER BY a.id \n#pageable\n", 
        /*countQuery="SELECT count(a.*) "
            + "FROM author a left outer join mappable_natural_person p on a.id = p.provenance_id "
            + "WHERE p.update_time is null OR (p.provenance_name='biblio_db' and a.update_time>p.update_time) \n#pageable\n",*/
        nativeQuery=true)
public List<Author> findAuthorsUpdatedAndNew(Pageable pageable);

هناك حاجة إلى countQuery (التي تم تعليقها في كتلة التعليمات البرمجية) لاستخدام Page<Author> كنوع الإرجاع للاستعلام ، والخطوط الجديدة حول التعليق "# pageable" ضرورية لتجنب خطأ وقت التشغيل على عدد المعلمات المتوقعة (الحل البديل للمشكلة). آمل أن يتم إصلاح هذا الخطأ قريبًا ...


جرب هذا:

public interface UserRepository extends JpaRepository<User, Long> {
  @Query(value = "SELECT * FROM USERS WHERE LASTNAME = ?1 ORDER BY /*#pageable*/",
    countQuery = "SELECT count(*) FROM USERS WHERE LASTNAME = ?1",
    nativeQuery = true)
  Page<User> findByLastname(String lastname, Pageable pageable);
}

( "/* */" Oracle notation )


فقط للسجل ، باستخدام H2 كقاعدة بيانات اختبار ، و MySQL في وقت التشغيل ، يعمل هذا النهج (المثال هو أحدث كائن في المجموعة ):

@Query(value = "SELECT t.* FROM t LEFT JOIN t AS t_newer " +
        "ON t.object_id = t_newer.object_id AND t.id < t_newer.id AND o_newer.user_id IN (:user_ids) " +
        "WHERE t_newer.id IS NULL AND t.user_id IN (:user_ids) " +
        "ORDER BY t.id DESC \n-- #pageable\n",
        countQuery = "SELECT COUNT(1) FROM t WHERE t.user_id IN (:user_ids) GROUP BY t.object_id, t.user_id",
        nativeQuery = true)
Page<T> findByUserIdInGroupByObjectId(@Param("user_ids") Set<Integer> userIds, Pageable pageable);

Spring Data JPA 1.10.5، H2 1.4.194، MySQL Community Server 5.7.11-log (innodb_version 5.7.11).


لدي نفس الأعراض بالضبط مثل Lasneyx. الحل الخاص بي للاستعلام الأصلي Postgres

@Query(value = "select * from users where user_type in (:userTypes) and user_context='abc'--#pageable\n", nativeQuery = true)
List<User> getUsersByTypes(@Param("userTypes") List<String> userTypes, Pageable pageable);

يعمل هذا الرمز مع PostgreSQL و MySQL:

public interface UserRepository extends JpaRepository<User, Long> {
  @Query(value = "SELECT * FROM USERS WHERE LASTNAME = ?1 ORDER BY ?#{#pageable}",
    countQuery = "SELECT count(*) FROM USERS WHERE LASTNAME = ?1",
    nativeQuery = true)
  Page<User> findByLastname(String lastname, Pageable pageable);
}

ORDER BY ?#{#pageable} Pageable ORDER BY ?#{#pageable} Pageable لـ Pageable . countQuery هو Page<> .


أنها لا تعمل على النحو التالي:

public interface UserRepository extends JpaRepository<User, Long> {
    @Query(value = "select * from (select (@rowid\\:[email protected]+1) as RN, u.* from USERS u, (SELECT @rowid\\:=0) as init where  LASTNAME = ?1) as total"+
        "where RN between ?#{#pageable.offset-1} and ?#{#pageable.offset + #pageable.pageSize}",
    countQuery = "SELECT count(*) FROM USERS WHERE LASTNAME = ?1",
    nativeQuery = true)
    Page<User> findByLastname(String lastname, Pageable pageable);
}




spring-data-jpa