HHH-8477 - Cannot create named queries at runtime - exception results

This commit is contained in:
Steve Ebersole 2013-09-09 14:14:27 -05:00
parent d995bb9bb9
commit b8b586a65e
3 changed files with 70 additions and 31 deletions

View File

@ -368,26 +368,59 @@ public PersistenceUnitUtil getPersistenceUnitUtil() {
public void addNamedQuery(String name, Query query) { public void addNamedQuery(String name, Query query) {
validateNotClosed(); validateNotClosed();
if ( StoredProcedureQueryImpl.class.isInstance( query ) ) { // NOTE : we use Query#unwrap here (rather than direct type checking) to account for possibly wrapped
final ProcedureCall procedureCall = ( (StoredProcedureQueryImpl) query ).getHibernateProcedureCall(); // query implementations
sessionFactory.getNamedQueryRepository().registerNamedProcedureCallMemento( name, procedureCall.extractMemento( query.getHints() ) );
} // first, handle StoredProcedureQuery
else if ( ! HibernateQuery.class.isInstance( query ) ) { try {
throw new PersistenceException( "Cannot use query non-Hibernate EntityManager query as basis for named query" ); final StoredProcedureQueryImpl unwrapped = query.unwrap( StoredProcedureQueryImpl.class );
} if ( unwrapped != null ) {
else { addNamedStoredProcedureQuery( name, unwrapped );
// create and register the proper NamedQueryDefinition... return;
final org.hibernate.Query hibernateQuery = ( (HibernateQuery) query ).getHibernateQuery();
if ( org.hibernate.SQLQuery.class.isInstance( hibernateQuery ) ) {
sessionFactory.registerNamedSQLQueryDefinition(
name,
extractSqlQueryDefinition( (org.hibernate.SQLQuery) hibernateQuery, name )
);
}
else {
sessionFactory.registerNamedQueryDefinition( name, extractHqlQueryDefinition( hibernateQuery, name ) );
} }
} }
catch ( PersistenceException ignore ) {
// this means 'query' is not a StoredProcedureQueryImpl
}
// then try as a native-SQL or JPQL query
try {
final HibernateQuery unwrapped = query.unwrap( HibernateQuery.class );
if ( unwrapped != null ) {
// create and register the proper NamedQueryDefinition...
final org.hibernate.Query hibernateQuery = ( (HibernateQuery) query ).getHibernateQuery();
if ( org.hibernate.SQLQuery.class.isInstance( hibernateQuery ) ) {
sessionFactory.registerNamedSQLQueryDefinition(
name,
extractSqlQueryDefinition( (org.hibernate.SQLQuery) hibernateQuery, name )
);
}
else {
sessionFactory.registerNamedQueryDefinition( name, extractHqlQueryDefinition( hibernateQuery, name ) );
}
return;
}
}
catch ( PersistenceException ignore ) {
// this means 'query' is not a native-SQL or JPQL query
}
// if we get here, we are unsure how to properly unwrap the incoming query to extract the needed information
throw new PersistenceException(
String.format(
"Unsure how to how to properly unwrap given Query [%s] as basis for named query",
query
)
);
}
private void addNamedStoredProcedureQuery(String name, StoredProcedureQueryImpl query) {
final ProcedureCall procedureCall = query.getHibernateProcedureCall();
sessionFactory.getNamedQueryRepository().registerNamedProcedureCallMemento(
name,
procedureCall.extractMemento( query.getHints() )
);
} }
private NamedSQLQueryDefinition extractSqlQueryDefinition(org.hibernate.SQLQuery nativeSqlQuery, String name) { private NamedSQLQueryDefinition extractSqlQueryDefinition(org.hibernate.SQLQuery nativeSqlQuery, String name) {

View File

@ -41,6 +41,7 @@
import javax.persistence.ParameterMode; import javax.persistence.ParameterMode;
import javax.persistence.PersistenceException; import javax.persistence.PersistenceException;
import javax.persistence.Query; import javax.persistence.Query;
import javax.persistence.StoredProcedureQuery;
import javax.persistence.TemporalType; import javax.persistence.TemporalType;
import javax.persistence.TypedQuery; import javax.persistence.TypedQuery;
@ -444,19 +445,21 @@ public <T> T unwrap(Class<T> tClass) {
if ( org.hibernate.Query.class.isAssignableFrom( tClass ) ) { if ( org.hibernate.Query.class.isAssignableFrom( tClass ) ) {
return (T) query; return (T) query;
} }
else { if ( QueryImpl.class.isAssignableFrom( tClass ) ) {
try { return (T) this;
return (T) this;
}
catch ( ClassCastException cce ) {
PersistenceException pe = new PersistenceException(
"Unsupported unwrap target type [" + tClass.getName() + "]"
);
//It's probably against the spec to not mark the tx for rollback but it will be easier for people
//getEntityManager().handlePersistenceException( pe );
throw pe;
}
} }
if ( HibernateQuery.class.isAssignableFrom( tClass ) ) {
return (T) this;
}
throw new PersistenceException(
String.format(
"Unsure how to unwrap %s impl [%s] as requested type [%s]",
Query.class.getSimpleName(),
this.getClass().getName(),
tClass.getName()
)
);
} }
@Override @Override

View File

@ -385,7 +385,10 @@ public <T> T unwrap(Class<T> cls) {
else if ( ProcedureOutputs.class.isAssignableFrom( cls ) ) { else if ( ProcedureOutputs.class.isAssignableFrom( cls ) ) {
return (T) outputs(); return (T) outputs();
} }
else if ( BaseQueryImpl.class.isAssignableFrom( cls ) ) { else if ( StoredProcedureQueryImpl.class.isAssignableFrom( cls ) ) {
return (T) this;
}
else if ( StoredProcedureQuery.class.equals( cls ) ) {
return (T) this; return (T) this;
} }