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 class EntityManagerFactoryImpl implements HibernateEntityManagerFactory {
public void addNamedQuery(String name, Query query) {
validateNotClosed();
if ( StoredProcedureQueryImpl.class.isInstance( query ) ) {
final ProcedureCall procedureCall = ( (StoredProcedureQueryImpl) query ).getHibernateProcedureCall();
sessionFactory.getNamedQueryRepository().registerNamedProcedureCallMemento( name, procedureCall.extractMemento( query.getHints() ) );
}
else if ( ! HibernateQuery.class.isInstance( query ) ) {
throw new PersistenceException( "Cannot use query non-Hibernate EntityManager query as basis for named query" );
}
else {
// 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 ) );
// NOTE : we use Query#unwrap here (rather than direct type checking) to account for possibly wrapped
// query implementations
// first, handle StoredProcedureQuery
try {
final StoredProcedureQueryImpl unwrapped = query.unwrap( StoredProcedureQueryImpl.class );
if ( unwrapped != null ) {
addNamedStoredProcedureQuery( name, unwrapped );
return;
}
}
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) {

View File

@ -41,6 +41,7 @@ import javax.persistence.NonUniqueResultException;
import javax.persistence.ParameterMode;
import javax.persistence.PersistenceException;
import javax.persistence.Query;
import javax.persistence.StoredProcedureQuery;
import javax.persistence.TemporalType;
import javax.persistence.TypedQuery;
@ -444,19 +445,21 @@ public class QueryImpl<X> extends AbstractQueryImpl<X> implements TypedQuery<X>,
if ( org.hibernate.Query.class.isAssignableFrom( tClass ) ) {
return (T) query;
}
else {
try {
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 ( QueryImpl.class.isAssignableFrom( tClass ) ) {
return (T) this;
}
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

View File

@ -385,7 +385,10 @@ public class StoredProcedureQueryImpl extends BaseQueryImpl implements StoredPro
else if ( ProcedureOutputs.class.isAssignableFrom( cls ) ) {
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;
}