@@ -433,52 +433,63 @@ public List<T> findAll(Specification<T> spec, Sort sort) {
433
433
/* (non-Javadoc)
434
434
* @see org.springframework.data.repository.query.QueryByExampleExecutor#findOne(org.springframework.data.domain.Example)
435
435
*/
436
+ @ SuppressWarnings ("unchecked" )
436
437
@ Override
437
- public <S extends T > T findOne (Example <S > example ) {
438
- return findOne (new ExampleSpecification <T >((Example ) example ));
438
+ public <S extends T > S findOne (Example <S > example ) {
439
+ try {
440
+ return getQuery (new ExampleSpecification <S >(example ), example .getResultType (), (Sort ) null ).getSingleResult ();
441
+ } catch (NoResultException e ) {
442
+ return null ;
443
+ }
439
444
}
440
445
441
446
/* (non-Javadoc)
442
447
* @see org.springframework.data.repository.query.QueryByExampleExecutor#count(org.springframework.data.domain.Example)
443
448
*/
449
+ @ SuppressWarnings ("unchecked" )
444
450
@ Override
445
451
public <S extends T > long count (Example <S > example ) {
446
- return count ( new ExampleSpecification <T >(( Example ) example ));
452
+ return executeCountQuery ( getCountQuery ( new ExampleSpecification <S >( example ), example . getResultType () ));
447
453
}
448
454
449
455
/* (non-Javadoc)
450
456
* @see org.springframework.data.repository.query.QueryByExampleExecutor#exists(org.springframework.data.domain.Example)
451
457
*/
452
458
@ Override
453
459
public <S extends T > boolean exists (Example <S > example ) {
454
- return !getQuery (new ExampleSpecification <T >((Example ) example ), (Sort ) null ).getResultList ().isEmpty ();
460
+ return !getQuery (new ExampleSpecification <S >(example ), example .getResultType (), (Sort ) null ).getResultList ()
461
+ .isEmpty ();
455
462
}
456
463
457
464
/*
458
465
* (non-Javadoc)
459
466
* @see org.springframework.data.repository.query.QueryByExampleExecutor#findAll(org.springframework.data.domain.Example)
460
467
*/
461
468
@ Override
462
- public <S extends T > List <T > findAll (Example <S > example ) {
463
- return findAll (new ExampleSpecification <T >(( Example ) example ) );
469
+ public <S extends T > List <S > findAll (Example <S > example ) {
470
+ return getQuery (new ExampleSpecification <S >( example ), example . getResultType (), ( Sort ) null ). getResultList ( );
464
471
}
465
472
466
473
/*
467
474
* (non-Javadoc)
468
475
* @see org.springframework.data.repository.query.QueryByExampleExecutor#findAll(org.springframework.data.domain.Example, org.springframework.data.domain.Sort)
469
476
*/
470
477
@ Override
471
- public <S extends T > List <T > findAll (Example <S > example , Sort sort ) {
472
- return findAll (new ExampleSpecification <T >(( Example ) example ), sort );
478
+ public <S extends T > List <S > findAll (Example <S > example , Sort sort ) {
479
+ return getQuery (new ExampleSpecification <S >( example ), example . getResultType ( ), sort ). getResultList ( );
473
480
}
474
481
475
482
/*
476
483
* (non-Javadoc)
477
484
* @see org.springframework.data.repository.query.QueryByExampleExecutor#findAll(org.springframework.data.domain.Example, org.springframework.data.domain.Pageable)
478
485
*/
479
486
@ Override
480
- public <S extends T > Page <T > findAll (Example <S > example , Pageable pageable ) {
481
- return findAll (new ExampleSpecification <T >((Example ) example ), pageable );
487
+ public <S extends T > Page <S > findAll (Example <S > example , Pageable pageable ) {
488
+
489
+ ExampleSpecification <S > spec = new ExampleSpecification <S >(example );
490
+ TypedQuery <S > query = getQuery (new ExampleSpecification <S >(example ), example .getResultType (), pageable );
491
+ return pageable == null ? new PageImpl <S >(query .getResultList ())
492
+ : readPage (query , example .getResultType (), pageable , spec );
482
493
}
483
494
484
495
/*
@@ -496,7 +507,6 @@ public long count() {
496
507
*/
497
508
@ Override
498
509
public long count (Specification <T > spec ) {
499
-
500
510
return executeCountQuery (getCountQuery (spec ));
501
511
}
502
512
@@ -572,14 +582,29 @@ public void flush() {
572
582
* @return
573
583
*/
574
584
protected Page <T > readPage (TypedQuery <T > query , Pageable pageable , Specification <T > spec ) {
585
+ return readPage (query , getDomainClass (), pageable , spec );
586
+ }
587
+
588
+ /**
589
+ * Reads the given {@link TypedQuery} into a {@link Page} applying the given {@link Pageable} and
590
+ * {@link Specification}.
591
+ *
592
+ * @param query must not be {@literal null}.
593
+ * @param domainClass must not be {@literal null}.
594
+ * @param spec can be {@literal null}.
595
+ * @param pageable can be {@literal null}.
596
+ * @return
597
+ */
598
+ protected <S extends T > Page <S > readPage (TypedQuery <S > query , Class <S > domainClass , Pageable pageable ,
599
+ Specification <S > spec ) {
575
600
576
601
query .setFirstResult (pageable .getOffset ());
577
602
query .setMaxResults (pageable .getPageSize ());
578
603
579
- Long total = executeCountQuery (getCountQuery (spec ));
580
- List <T > content = total > pageable .getOffset () ? query .getResultList () : Collections .<T > emptyList ();
604
+ Long total = executeCountQuery (getCountQuery (spec , domainClass ));
605
+ List <S > content = total > pageable .getOffset () ? query .getResultList () : Collections .<S > emptyList ();
581
606
582
- return new PageImpl <T >(content , pageable , total );
607
+ return new PageImpl <S >(content , pageable , total );
583
608
}
584
609
585
610
/**
@@ -592,7 +617,21 @@ protected Page<T> readPage(TypedQuery<T> query, Pageable pageable, Specification
592
617
protected TypedQuery <T > getQuery (Specification <T > spec , Pageable pageable ) {
593
618
594
619
Sort sort = pageable == null ? null : pageable .getSort ();
595
- return getQuery (spec , sort );
620
+ return getQuery (spec , getDomainClass (), sort );
621
+ }
622
+
623
+ /**
624
+ * Creates a new {@link TypedQuery} from the given {@link Specification}.
625
+ *
626
+ * @param spec can be {@literal null}.
627
+ * @param domainClass must not be {@literal null}.
628
+ * @param pageable can be {@literal null}.
629
+ * @return
630
+ */
631
+ protected <S extends T > TypedQuery <S > getQuery (Specification <S > spec , Class <S > domainClass , Pageable pageable ) {
632
+
633
+ Sort sort = pageable == null ? null : pageable .getSort ();
634
+ return getQuery (spec , domainClass , sort );
596
635
}
597
636
598
637
/**
@@ -603,11 +642,23 @@ protected TypedQuery<T> getQuery(Specification<T> spec, Pageable pageable) {
603
642
* @return
604
643
*/
605
644
protected TypedQuery <T > getQuery (Specification <T > spec , Sort sort ) {
645
+ return getQuery (spec , getDomainClass (), sort );
646
+ }
647
+
648
+ /**
649
+ * Creates a {@link TypedQuery} for the given {@link Specification} and {@link Sort}.
650
+ *
651
+ * @param spec can be {@literal null}.
652
+ * @param domainClass must not be {@literal null}.
653
+ * @param sort can be {@literal null}.
654
+ * @return
655
+ */
656
+ protected <S extends T > TypedQuery <S > getQuery (Specification <S > spec , Class <S > domainClass , Sort sort ) {
606
657
607
658
CriteriaBuilder builder = em .getCriteriaBuilder ();
608
- CriteriaQuery <T > query = builder .createQuery (getDomainClass () );
659
+ CriteriaQuery <S > query = builder .createQuery (domainClass );
609
660
610
- Root <T > root = applySpecificationToCriteria (spec , query );
661
+ Root <S > root = applySpecificationToCriteria (spec , domainClass , query );
611
662
query .select (root );
612
663
613
664
if (sort != null ) {
@@ -624,11 +675,22 @@ protected TypedQuery<T> getQuery(Specification<T> spec, Sort sort) {
624
675
* @return
625
676
*/
626
677
protected TypedQuery <Long > getCountQuery (Specification <T > spec ) {
678
+ return getCountQuery (spec , getDomainClass ());
679
+ }
680
+
681
+ /**
682
+ * Creates a new count query for the given {@link Specification}.
683
+ *
684
+ * @param spec can be {@literal null}.
685
+ * @param domainClass must not be {@literal null}.
686
+ * @return
687
+ */
688
+ protected <S extends T > TypedQuery <Long > getCountQuery (Specification <S > spec , Class <S > domainClass ) {
627
689
628
690
CriteriaBuilder builder = em .getCriteriaBuilder ();
629
691
CriteriaQuery <Long > query = builder .createQuery (Long .class );
630
692
631
- Root <T > root = applySpecificationToCriteria (spec , query );
693
+ Root <S > root = applySpecificationToCriteria (spec , domainClass , query );
632
694
633
695
if (query .isDistinct ()) {
634
696
query .select (builder .countDistinct (root ));
@@ -647,9 +709,24 @@ protected TypedQuery<Long> getCountQuery(Specification<T> spec) {
647
709
* @return
648
710
*/
649
711
private <S > Root <T > applySpecificationToCriteria (Specification <T > spec , CriteriaQuery <S > query ) {
712
+ return applySpecificationToCriteria (spec , getDomainClass (), query );
713
+
714
+ }
715
+
716
+ /**
717
+ * Applies the given {@link Specification} to the given {@link CriteriaQuery}.
718
+ *
719
+ * @param spec can be {@literal null}.
720
+ * @param domainClass must not be {@literal null}.
721
+ * @param query must not be {@literal null}.
722
+ * @return
723
+ */
724
+ private <S , U extends T > Root <U > applySpecificationToCriteria (Specification <U > spec , Class <U > domainClass ,
725
+ CriteriaQuery <S > query ) {
650
726
651
727
Assert .notNull (query );
652
- Root <T > root = query .from (getDomainClass ());
728
+ Assert .notNull (domainClass );
729
+ Root <U > root = query .from (domainClass );
653
730
654
731
if (spec == null ) {
655
732
return root ;
@@ -665,14 +742,14 @@ private <S> Root<T> applySpecificationToCriteria(Specification<T> spec, Criteria
665
742
return root ;
666
743
}
667
744
668
- private TypedQuery <T > applyRepositoryMethodMetadata (TypedQuery <T > query ) {
745
+ private < S > TypedQuery <S > applyRepositoryMethodMetadata (TypedQuery <S > query ) {
669
746
670
747
if (metadata == null ) {
671
748
return query ;
672
749
}
673
750
674
751
LockModeType type = metadata .getLockModeType ();
675
- TypedQuery <T > toReturn = type == null ? query : query .setLockMode (type );
752
+ TypedQuery <S > toReturn = type == null ? query : query .setLockMode (type );
676
753
677
754
applyQueryHints (toReturn );
678
755
0 commit comments