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 ;
@@ -443,14 +445,16 @@ public <R> ReactiveNativeQuery<R> createReactiveNativeQuery(String sqlString, Cl
443
445
444
446
@ Override @ Deprecated (forRemoval = true )
445
447
public <R > ReactiveNativeQuery <R > createReactiveNativeQuery (String sqlString , String resultSetMappingName ) {
448
+ if ( isEmpty ( resultSetMappingName ) ) {
449
+ throw new IllegalArgumentException ( "Result set mapping name was not specified" );
450
+ }
451
+
446
452
checkOpen ();
447
453
pulseTransactionCoordinator ();
448
454
delayedAfterCompletion ();
449
455
450
456
try {
451
- return isNotEmpty ( resultSetMappingName )
452
- ? new ReactiveNativeQueryImpl <>( sqlString , getResultSetMappingMemento ( resultSetMappingName ), this )
453
- : new ReactiveNativeQueryImpl <>( sqlString , this );
457
+ return new ReactiveNativeQueryImpl <>( sqlString , getResultSetMappingMemento ( resultSetMappingName ), null , this );
454
458
//TODO: why no applyQuerySettingsAndHints( query ); ???
455
459
}
456
460
catch (RuntimeException he ) {
@@ -497,9 +501,78 @@ private <R> ReactiveSelectionQuery<R> createSelectionQuery(String hql, Class<R>
497
501
return query ;
498
502
}
499
503
504
+ @ Override
505
+ public <R > ReactiveQueryImplementor <R > createReactiveNamedQuery (String name ) {
506
+ checksBeforeQueryCreation ();
507
+ try {
508
+ return (ReactiveQueryImplementor <R >) buildNamedQuery (
509
+ name ,
510
+ this ::createSqmQueryImplementor ,
511
+ this ::createNativeQueryImplementor
512
+ );
513
+ }
514
+ catch (RuntimeException e ) {
515
+ throw convertNamedQueryException ( e );
516
+ }
517
+ }
518
+
500
519
@ Override
501
520
public <R > ReactiveQueryImplementor <R > createReactiveNamedQuery (String name , Class <R > resultType ) {
502
- return (ReactiveQueryImplementor <R >) buildNamedQuery ( name , resultType );
521
+ checksBeforeQueryCreation ();
522
+ if ( resultType == null ) {
523
+ throw new IllegalArgumentException ( "Result class is null" );
524
+ }
525
+ try {
526
+ return buildNamedQuery (
527
+ name ,
528
+ memento -> createReactiveSqmQueryImplementor ( resultType , memento ),
529
+ memento -> createReactiveNativeQueryImplementor ( resultType , memento )
530
+ );
531
+ }
532
+ catch (RuntimeException e ) {
533
+ throw convertNamedQueryException ( e );
534
+ }
535
+ }
536
+
537
+ private void checksBeforeQueryCreation () {
538
+ checkOpen ();
539
+ checkTransactionSynchStatus ();
540
+ }
541
+
542
+ protected <T > ReactiveNativeQueryImpl <T > createReactiveNativeQueryImplementor (Class <T > resultType , NamedNativeQueryMemento <?> memento ) {
543
+ final NativeQueryImplementor <T > query = memento .toQuery (this , resultType );
544
+ if ( isEmpty ( query .getComment () ) ) {
545
+ query .setComment ( "dynamic native SQL query" );
546
+ }
547
+ applyQuerySettingsAndHints ( query );
548
+ return (ReactiveNativeQueryImpl <T >) query ;
549
+ }
550
+
551
+ protected <T > ReactiveQuerySqmImpl <T > createReactiveSqmQueryImplementor (Class <T > resultType , NamedSqmQueryMemento <?> memento ) {
552
+ final SqmQueryImplementor <T > query = memento .toQuery ( this , resultType );
553
+ if ( isEmpty ( query .getComment () ) ) {
554
+ query .setComment ( "dynamic query" );
555
+ }
556
+ applyQuerySettingsAndHints ( query );
557
+ if ( memento .getLockOptions () != null ) {
558
+ query .setLockOptions ( memento .getLockOptions () );
559
+ }
560
+ return (ReactiveQuerySqmImpl <T >) query ;
561
+ }
562
+
563
+ private RuntimeException convertNamedQueryException (RuntimeException e ) {
564
+ if ( e instanceof UnknownNamedQueryException ) {
565
+ // JPA expects this to mark the transaction for rollback only
566
+ getTransactionCoordinator ().getTransactionDriverControl ().markRollbackOnly ();
567
+ // it also expects an IllegalArgumentException, so wrap UnknownNamedQueryException
568
+ return new IllegalArgumentException ( e .getMessage (), e );
569
+ }
570
+ else if ( e instanceof IllegalArgumentException ) {
571
+ return e ;
572
+ }
573
+ else {
574
+ return getExceptionConverter ().convert ( e );
575
+ }
503
576
}
504
577
505
578
@ Override
@@ -584,7 +657,7 @@ public <R> ReactiveNativeQuery<R> createReactiveNativeQuery(String queryString,
584
657
delayedAfterCompletion ();
585
658
586
659
try {
587
- final ReactiveNativeQueryImpl <R > query = new ReactiveNativeQueryImpl <>( queryString , this );
660
+ final ReactiveNativeQueryImpl <R > query = new ReactiveNativeQueryImpl <>( queryString , null , this );
588
661
addAffectedEntities ( affectedEntities , query );
589
662
if ( isEmpty ( query .getComment () ) ) {
590
663
query .setComment ( "dynamic native SQL query" );
@@ -622,12 +695,11 @@ public <R> ReactiveNativeQueryImpl<R> createReactiveNativeQuery(String queryStri
622
695
checkOpen ();
623
696
pulseTransactionCoordinator ();
624
697
delayedAfterCompletion ();
625
-
698
+ // Should we throw an exception?
699
+ NamedResultSetMappingMemento memento = resultSetMapping == null ? null : getResultSetMappingMemento ( resultSetMapping .getName () );
626
700
try {
627
701
// Same approach as AbstractSharedSessionContract#createNativeQuery(String, String)
628
- final ReactiveNativeQueryImpl <R > nativeQuery = resultSetMapping != null
629
- ? new ReactiveNativeQueryImpl <>( queryString , getResultSetMappingMemento ( resultSetMapping .getName () ), this )
630
- : new ReactiveNativeQueryImpl <>( queryString , this );
702
+ final ReactiveNativeQueryImpl <R > nativeQuery = new ReactiveNativeQueryImpl <>( queryString , memento , null , this );
631
703
applyQuerySettingsAndHints ( nativeQuery );
632
704
return nativeQuery ;
633
705
}
@@ -652,20 +724,13 @@ public <T> ResultSetMapping<T> getResultSetMapping(Class<T> resultType, String m
652
724
if ( mapping == null ) {
653
725
throw new IllegalArgumentException ( "result set mapping does not exist: " + mappingName );
654
726
}
655
- //
656
- // ResultSetMappingImpl resultSetMapping = new ResultSetMappingImpl( "impl" );
657
- // if ( resultType != null ) {
658
- // Class<?> mappedResultType = resultSetMapping.;
659
- // if ( !resultType.equals( mappedResultType ) ) {
660
- // throw new IllegalArgumentException( "incorrect result type for result set mapping: " + mappingName + " has type " + mappedResultType.getName() );
661
- // }
662
- // }
663
727
664
728
return new ResultSetMapping <>() {
665
729
@ Override
666
730
public String getName () {
667
731
return mappingName ;
668
732
}
733
+
669
734
@ Override
670
735
public Class <T > getResultType () {
671
736
return resultType ;
0 commit comments