private Map checkNamedQueries() throws HibernateException { Map errors = new HashMap(); // Check named HQL queries log.debug("Checking " + namedQueries.size() + " named HQL queries"); Iterator itr = namedQueries.entrySet().iterator(); while (itr.hasNext()) { final Map.Entry entry = (Map.Entry) itr.next(); final String queryName = (String) entry.getKey(); final NamedQueryDefinition qd = (NamedQueryDefinition) entry.getValue(); // this will throw an error if there's something wrong. try { log.debug("Checking named query: " + queryName); // TODO: BUG! this currently fails for named queries for non-POJO entities queryPlanCache.getHQLQueryPlan(qd.getQueryString(), false, CollectionHelper.EMPTY_MAP); } catch (QueryException e) { errors.put(queryName, e); } catch (MappingException e) { errors.put(queryName, e); } } log.debug("Checking " + namedSqlQueries.size() + " named SQL queries"); itr = namedSqlQueries.entrySet().iterator(); while (itr.hasNext()) { final Map.Entry entry = (Map.Entry) itr.next(); final String queryName = (String) entry.getKey(); final NamedSQLQueryDefinition qd = (NamedSQLQueryDefinition) entry.getValue(); // this will throw an error if there's something wrong. try { log.debug("Checking named SQL query: " + queryName); // TODO : would be really nice to cache the spec on the query-def so as to not have to // re-calc the hash; // currently not doable though because of the resultset-ref stuff... NativeSQLQuerySpecification spec; if (qd.getResultSetRef() != null) { ResultSetMappingDefinition definition = (ResultSetMappingDefinition) sqlResultSetMappings.get(qd.getResultSetRef()); if (definition == null) { throw new MappingException( "Unable to find resultset-ref definition: " + qd.getResultSetRef()); } spec = new NativeSQLQuerySpecification( qd.getQueryString(), definition.getQueryReturns(), qd.getQuerySpaces()); } else { spec = new NativeSQLQuerySpecification( qd.getQueryString(), qd.getQueryReturns(), qd.getQuerySpaces()); } queryPlanCache.getNativeSQLQueryPlan(spec); } catch (QueryException e) { errors.put(queryName, e); } catch (MappingException e) { errors.put(queryName, e); } } return errors; }
public <T> TypedQuery<T> createNamedQuery(String name, Class<T> resultClass) { try { /* * Get the named query. * If the named query is a SQL query, get the expected returned type from the query definition * or its associated result set mapping * If the named query is a HQL query, use getReturnType() */ org.hibernate.Query namedQuery = getSession().getNamedQuery(name); // TODO clean this up to avoid downcasting final SessionFactoryImplementor factoryImplementor = (SessionFactoryImplementor) entityManagerFactory.getSessionFactory(); final NamedSQLQueryDefinition queryDefinition = factoryImplementor.getNamedSQLQuery(name); try { if (queryDefinition != null) { Class<?> actualReturnedClass; final NativeSQLQueryReturn[] queryReturns; if (queryDefinition.getQueryReturns() != null) { queryReturns = queryDefinition.getQueryReturns(); } else if (queryDefinition.getResultSetRef() != null) { final ResultSetMappingDefinition rsMapping = factoryImplementor.getResultSetMapping(queryDefinition.getResultSetRef()); queryReturns = rsMapping.getQueryReturns(); } else { throw new AssertionFailure( "Unsupported named query model. Please report the bug in Hibernate EntityManager"); } if (queryReturns.length > 1) { throw new IllegalArgumentException( "Cannot create TypedQuery for query with more than one return"); } final NativeSQLQueryReturn nativeSQLQueryReturn = queryReturns[0]; if (nativeSQLQueryReturn instanceof NativeSQLQueryRootReturn) { final String entityClassName = ((NativeSQLQueryRootReturn) nativeSQLQueryReturn).getReturnEntityName(); try { actualReturnedClass = ReflectHelper.classForName(entityClassName, AbstractEntityManagerImpl.class); } catch (ClassNotFoundException e) { throw new AssertionFailure( "Unable to instantiate class declared on named native query: " + name + " " + entityClassName); } if (!resultClass.isAssignableFrom(actualReturnedClass)) { throw buildIncompatibleException(resultClass, actualReturnedClass); } } else { // TODO support other NativeSQLQueryReturn type. For now let it go. } } else { if (namedQuery.getReturnTypes().length != 1) { throw new IllegalArgumentException( "Cannot create TypedQuery for query with more than one return"); } if (!resultClass.isAssignableFrom(namedQuery.getReturnTypes()[0].getReturnedClass())) { throw buildIncompatibleException( resultClass, namedQuery.getReturnTypes()[0].getReturnedClass()); } } return new QueryImpl<T>(namedQuery, this); } catch (HibernateException he) { throw convert(he); } } catch (MappingException e) { throw new IllegalArgumentException("Named query not found: " + name); } }