72
72
import org .hibernate .proxy .HibernateProxy ;
73
73
import org .hibernate .proxy .LazyInitializer ;
74
74
import org .hibernate .query .IllegalMutationQueryException ;
75
+ import org .hibernate .query .UnknownNamedQueryException ;
75
76
import org .hibernate .query .criteria .JpaCriteriaInsert ;
76
77
import org .hibernate .query .hql .spi .SqmQueryImplementor ;
77
78
import org .hibernate .query .named .NamedResultSetMappingMemento ;
78
79
import org .hibernate .query .spi .HqlInterpretation ;
79
80
import org .hibernate .query .spi .QueryImplementor ;
81
+ import org .hibernate .query .sql .spi .NamedNativeQueryMemento ;
80
82
import org .hibernate .query .sql .spi .NativeQueryImplementor ;
81
83
import org .hibernate .query .sqm .internal .SqmUtil ;
84
+ import org .hibernate .query .sqm .spi .NamedSqmQueryMemento ;
82
85
import org .hibernate .query .sqm .tree .SqmStatement ;
83
86
import org .hibernate .query .sqm .tree .delete .SqmDeleteStatement ;
84
87
import org .hibernate .query .sqm .tree .insert .SqmInsertStatement ;
131
134
import static org .hibernate .engine .spi .NaturalIdResolutions .INVALID_NATURAL_ID_REFERENCE ;
132
135
import static org .hibernate .event .spi .LoadEventListener .IMMEDIATE_LOAD ;
133
136
import static org .hibernate .internal .util .StringHelper .isEmpty ;
134
- import static org .hibernate .internal .util .StringHelper .isNotEmpty ;
135
137
import static org .hibernate .proxy .HibernateProxy .extractLazyInitializer ;
136
138
import static org .hibernate .reactive .common .InternalStateAssertions .assertUseOnEventLoop ;
137
139
import static org .hibernate .reactive .persister .entity .impl .ReactiveEntityPersister .forceInitialize ;
@@ -389,7 +391,7 @@ public <T> ReactiveNativeQueryImplementor<T> createReactiveNativeQuery(String sq
389
391
delayedAfterCompletion ();
390
392
391
393
try {
392
- final ReactiveNativeQueryImpl <T > query = new ReactiveNativeQueryImpl <>( sqlString , this );
394
+ final ReactiveNativeQueryImpl <T > query = new ReactiveNativeQueryImpl <>( sqlString , null , this );
393
395
if ( isEmpty ( query .getComment () ) ) {
394
396
query .setComment ( "dynamic native SQL query" );
395
397
}
@@ -445,32 +447,34 @@ public <R> ReactiveNativeQuery<R> createReactiveNativeQuery(String sqlString, Cl
445
447
}
446
448
}
447
449
450
+ @ Override
451
+ public <R > ReactiveNativeQuery <R > createReactiveNativeQuery (String sqlString , String resultSetMappingName , Class <R > resultClass ) {
452
+ final ReactiveNativeQuery <R > query = createReactiveNativeQuery ( sqlString , resultSetMappingName );
453
+ if ( Tuple .class .equals ( resultClass ) ) {
454
+ query .setTupleTransformer ( new NativeQueryTupleTransformer () );
455
+ }
456
+ return query ;
457
+ }
458
+
448
459
@ Override
449
460
public <R > ReactiveNativeQuery <R > createReactiveNativeQuery (String sqlString , String resultSetMappingName ) {
461
+ if ( isEmpty ( resultSetMappingName ) ) {
462
+ throw new IllegalArgumentException ( "Result set mapping name was not specified" );
463
+ }
464
+
450
465
checkOpen ();
451
466
pulseTransactionCoordinator ();
452
467
delayedAfterCompletion ();
453
468
454
469
try {
455
- return isNotEmpty ( resultSetMappingName )
456
- ? new ReactiveNativeQueryImpl <>( sqlString , getResultSetMappingMemento ( resultSetMappingName ), this )
457
- : new ReactiveNativeQueryImpl <>( sqlString , this );
470
+ return new ReactiveNativeQueryImpl <>( sqlString , getResultSetMappingMemento ( resultSetMappingName ), null , this );
458
471
//TODO: why no applyQuerySettingsAndHints( query ); ???
459
472
}
460
473
catch (RuntimeException he ) {
461
474
throw getExceptionConverter ().convert ( he );
462
475
}
463
476
}
464
477
465
- @ Override
466
- public <R > ReactiveNativeQuery <R > createReactiveNativeQuery (String sqlString , String resultSetMappingName , Class <R > resultClass ) {
467
- final ReactiveNativeQuery <R > query = createReactiveNativeQuery ( sqlString , resultSetMappingName );
468
- if ( Tuple .class .equals ( resultClass ) ) {
469
- query .setTupleTransformer ( new NativeQueryTupleTransformer () );
470
- }
471
- return query ;
472
- }
473
-
474
478
@ Override
475
479
public <R > ReactiveSelectionQuery <R > createReactiveSelectionQuery (String hqlString , Class <R > resultType ) {
476
480
return interpretAndCreateSelectionQuery ( hqlString , resultType );
@@ -503,9 +507,78 @@ private <R> ReactiveSelectionQuery<R> createSelectionQuery(String hql, Class<R>
503
507
return query ;
504
508
}
505
509
510
+ @ Override
511
+ public <R > ReactiveQueryImplementor <R > createReactiveNamedQuery (String name ) {
512
+ checksBeforeQueryCreation ();
513
+ try {
514
+ return (ReactiveQueryImplementor <R >) buildNamedQuery (
515
+ name ,
516
+ this ::createSqmQueryImplementor ,
517
+ this ::createNativeQueryImplementor
518
+ );
519
+ }
520
+ catch (RuntimeException e ) {
521
+ throw convertNamedQueryException ( e );
522
+ }
523
+ }
524
+
506
525
@ Override
507
526
public <R > ReactiveQueryImplementor <R > createReactiveNamedQuery (String name , Class <R > resultType ) {
508
- return (ReactiveQueryImplementor <R >) buildNamedQuery ( name , resultType );
527
+ checksBeforeQueryCreation ();
528
+ if ( resultType == null ) {
529
+ throw new IllegalArgumentException ( "Result class is null" );
530
+ }
531
+ try {
532
+ return buildNamedQuery (
533
+ name ,
534
+ memento -> createReactiveSqmQueryImplementor ( resultType , memento ),
535
+ memento -> createReactiveNativeQueryImplementor ( resultType , memento )
536
+ );
537
+ }
538
+ catch (RuntimeException e ) {
539
+ throw convertNamedQueryException ( e );
540
+ }
541
+ }
542
+
543
+ private void checksBeforeQueryCreation () {
544
+ checkOpen ();
545
+ checkTransactionSynchStatus ();
546
+ }
547
+
548
+ protected <T > ReactiveNativeQueryImpl <T > createReactiveNativeQueryImplementor (Class <T > resultType , NamedNativeQueryMemento <?> memento ) {
549
+ final NativeQueryImplementor <T > query = memento .toQuery (this , resultType );
550
+ if ( isEmpty ( query .getComment () ) ) {
551
+ query .setComment ( "dynamic native SQL query" );
552
+ }
553
+ applyQuerySettingsAndHints ( query );
554
+ return (ReactiveNativeQueryImpl <T >) query ;
555
+ }
556
+
557
+ protected <T > ReactiveQuerySqmImpl <T > createReactiveSqmQueryImplementor (Class <T > resultType , NamedSqmQueryMemento <?> memento ) {
558
+ final SqmQueryImplementor <T > query = memento .toQuery ( this , resultType );
559
+ if ( isEmpty ( query .getComment () ) ) {
560
+ query .setComment ( "dynamic query" );
561
+ }
562
+ applyQuerySettingsAndHints ( query );
563
+ if ( memento .getLockOptions () != null ) {
564
+ query .setLockOptions ( memento .getLockOptions () );
565
+ }
566
+ return (ReactiveQuerySqmImpl <T >) query ;
567
+ }
568
+
569
+ private RuntimeException convertNamedQueryException (RuntimeException e ) {
570
+ if ( e instanceof UnknownNamedQueryException ) {
571
+ // JPA expects this to mark the transaction for rollback only
572
+ getTransactionCoordinator ().getTransactionDriverControl ().markRollbackOnly ();
573
+ // it also expects an IllegalArgumentException, so wrap UnknownNamedQueryException
574
+ return new IllegalArgumentException ( e .getMessage (), e );
575
+ }
576
+ else if ( e instanceof IllegalArgumentException ) {
577
+ return e ;
578
+ }
579
+ else {
580
+ return getExceptionConverter ().convert ( e );
581
+ }
509
582
}
510
583
511
584
@ Override
@@ -590,7 +663,7 @@ public <R> ReactiveNativeQuery<R> createReactiveNativeQuery(String queryString,
590
663
delayedAfterCompletion ();
591
664
592
665
try {
593
- final ReactiveNativeQueryImpl <R > query = new ReactiveNativeQueryImpl <>( queryString , this );
666
+ final ReactiveNativeQueryImpl <R > query = new ReactiveNativeQueryImpl <>( queryString , null , this );
594
667
addAffectedEntities ( affectedEntities , query );
595
668
if ( isEmpty ( query .getComment () ) ) {
596
669
query .setComment ( "dynamic native SQL query" );
@@ -620,12 +693,11 @@ public <R> ReactiveNativeQueryImpl<R> createReactiveNativeQuery(String queryStri
620
693
checkOpen ();
621
694
pulseTransactionCoordinator ();
622
695
delayedAfterCompletion ();
623
-
696
+ // Should we throw an exception?
697
+ NamedResultSetMappingMemento memento = resultSetMapping == null ? null : getResultSetMappingMemento ( resultSetMapping .getName () );
624
698
try {
625
699
// Same approach as AbstractSharedSessionContract#createNativeQuery(String, String)
626
- final ReactiveNativeQueryImpl <R > nativeQuery = resultSetMapping != null
627
- ? new ReactiveNativeQueryImpl <>( queryString , getResultSetMappingMemento ( resultSetMapping .getName () ), this )
628
- : new ReactiveNativeQueryImpl <>( queryString , this );
700
+ final ReactiveNativeQueryImpl <R > nativeQuery = new ReactiveNativeQueryImpl <>( queryString , memento , null , this );
629
701
applyQuerySettingsAndHints ( nativeQuery );
630
702
return nativeQuery ;
631
703
}
@@ -650,20 +722,13 @@ public <T> ResultSetMapping<T> getResultSetMapping(Class<T> resultType, String m
650
722
if ( mapping == null ) {
651
723
throw new IllegalArgumentException ( "result set mapping does not exist: " + mappingName );
652
724
}
653
- //
654
- // ResultSetMappingImpl resultSetMapping = new ResultSetMappingImpl( "impl" );
655
- // if ( resultType != null ) {
656
- // Class<?> mappedResultType = resultSetMapping.;
657
- // if ( !resultType.equals( mappedResultType ) ) {
658
- // throw new IllegalArgumentException( "incorrect result type for result set mapping: " + mappingName + " has type " + mappedResultType.getName() );
659
- // }
660
- // }
661
725
662
726
return new ResultSetMapping <>() {
663
727
@ Override
664
728
public String getName () {
665
729
return mappingName ;
666
730
}
731
+
667
732
@ Override
668
733
public Class <T > getResultType () {
669
734
return resultType ;
0 commit comments