@@ -368,26 +368,59 @@ public PersistenceUnitUtil getPersistenceUnitUtil() {
368
368
public void addNamedQuery (String name , Query query ) {
369
369
validateNotClosed ();
370
370
371
- if ( StoredProcedureQueryImpl .class .isInstance ( query ) ) {
372
- final ProcedureCall procedureCall = ( (StoredProcedureQueryImpl ) query ).getHibernateProcedureCall ();
373
- sessionFactory .getNamedQueryRepository ().registerNamedProcedureCallMemento ( name , procedureCall .extractMemento ( query .getHints () ) );
374
- }
375
- else if ( ! HibernateQuery .class .isInstance ( query ) ) {
376
- throw new PersistenceException ( "Cannot use query non-Hibernate EntityManager query as basis for named query" );
377
- }
378
- else {
379
- // create and register the proper NamedQueryDefinition...
380
- final org .hibernate .Query hibernateQuery = ( (HibernateQuery ) query ).getHibernateQuery ();
381
- if ( org .hibernate .SQLQuery .class .isInstance ( hibernateQuery ) ) {
382
- sessionFactory .registerNamedSQLQueryDefinition (
383
- name ,
384
- extractSqlQueryDefinition ( (org .hibernate .SQLQuery ) hibernateQuery , name )
385
- );
371
+ // NOTE : we use Query#unwrap here (rather than direct type checking) to account for possibly wrapped
372
+ // query implementations
373
+
374
+ // first, handle StoredProcedureQuery
375
+ try {
376
+ final StoredProcedureQueryImpl unwrapped = query .unwrap ( StoredProcedureQueryImpl .class );
377
+ if ( unwrapped != null ) {
378
+ addNamedStoredProcedureQuery ( name , unwrapped );
379
+ return ;
386
380
}
387
- else {
388
- sessionFactory .registerNamedQueryDefinition ( name , extractHqlQueryDefinition ( hibernateQuery , name ) );
381
+ }
382
+ catch ( PersistenceException ignore ) {
383
+ // this means 'query' is not a StoredProcedureQueryImpl
384
+ }
385
+
386
+ // then try as a native-SQL or JPQL query
387
+ try {
388
+ final HibernateQuery unwrapped = query .unwrap ( HibernateQuery .class );
389
+ if ( unwrapped != null ) {
390
+ // create and register the proper NamedQueryDefinition...
391
+ final org .hibernate .Query hibernateQuery = ( (HibernateQuery ) query ).getHibernateQuery ();
392
+ if ( org .hibernate .SQLQuery .class .isInstance ( hibernateQuery ) ) {
393
+ sessionFactory .registerNamedSQLQueryDefinition (
394
+ name ,
395
+ extractSqlQueryDefinition ( (org .hibernate .SQLQuery ) hibernateQuery , name )
396
+ );
397
+ }
398
+ else {
399
+ sessionFactory .registerNamedQueryDefinition ( name , extractHqlQueryDefinition ( hibernateQuery , name ) );
400
+ }
401
+ return ;
389
402
}
390
403
}
404
+ catch ( PersistenceException ignore ) {
405
+ // this means 'query' is not a native-SQL or JPQL query
406
+ }
407
+
408
+
409
+ // if we get here, we are unsure how to properly unwrap the incoming query to extract the needed information
410
+ throw new PersistenceException (
411
+ String .format (
412
+ "Unsure how to how to properly unwrap given Query [%s] as basis for named query" ,
413
+ query
414
+ )
415
+ );
416
+ }
417
+
418
+ private void addNamedStoredProcedureQuery (String name , StoredProcedureQueryImpl query ) {
419
+ final ProcedureCall procedureCall = query .getHibernateProcedureCall ();
420
+ sessionFactory .getNamedQueryRepository ().registerNamedProcedureCallMemento (
421
+ name ,
422
+ procedureCall .extractMemento ( query .getHints () )
423
+ );
391
424
}
392
425
393
426
private NamedSQLQueryDefinition extractSqlQueryDefinition (org .hibernate .SQLQuery nativeSqlQuery , String name ) {
0 commit comments