protected QueryableCollection getQueryableCollection( String entityName, String propertyName, SessionFactoryImplementor factory) throws HibernateException { final PropertyMapping ownerMapping = (PropertyMapping) factory.getEntityPersister( entityName ); final Type type = ownerMapping.toType( propertyName ); if ( !type.isCollectionType() ) { throw new MappingException( "Property path [" + entityName + "." + propertyName + "] does not reference a collection" ); } final String role = ( (CollectionType) type ).getRole(); try { return (QueryableCollection) factory.getCollectionPersister( role ); } catch ( ClassCastException cce ) { throw new QueryException( "collection role is not queryable: " + role ); } catch ( Exception e ) { throw new QueryException( "collection role not found: " + role ); } }
private void createAssociationPathCriteriaMap() { final Iterator<CriteriaImpl.Subcriteria> iter = rootCriteria.iterateSubcriteria(); while ( iter.hasNext() ) { CriteriaImpl.Subcriteria crit = iter.next(); String wholeAssociationPath = getWholeAssociationPath( crit ); Object old = associationPathCriteriaMap.put( wholeAssociationPath, crit ); if ( old != null ) { throw new QueryException( "duplicate association path: " + wholeAssociationPath ); } JoinType joinType = crit.getJoinType(); old = associationPathJoinTypesMap.put( wholeAssociationPath, joinType ); if ( old != null ) { // TODO : not so sure this is needed... throw new QueryException( "duplicate association path: " + wholeAssociationPath ); } if ( crit.getWithClause() != null ) { this.withClauseMap.put( wholeAssociationPath, crit.getWithClause() ); } } }
private void validateLhs(FromReferenceNode lhs) { // make sure the lhs is "assignable"... if ( !lhs.isResolved() ) { throw new UnsupportedOperationException( "cannot validate assignablity of unresolved node" ); } if ( lhs.getDataType().isCollectionType() ) { throw new QueryException( "collections not assignable in update statements" ); } else if ( lhs.getDataType().isComponentType() ) { throw new QueryException( "Components currently not assignable in update statements" ); } else if ( lhs.getDataType().isEntityType() ) { // currently allowed... } // TODO : why aren't these the same? if ( lhs.getImpliedJoin() != null || lhs.getFromElement().isImplied() ) { throw new QueryException( "Implied join paths are not assignable in update statements" ); } }
public void end(QueryTranslatorImpl q) throws QueryException { ignoreInitialJoin = false; Type propertyType = getPropertyType(); if ( propertyType != null && propertyType.isCollectionType() ) { collectionRole = ( ( CollectionType ) propertyType ).getRole(); collectionName = q.createNameForCollection( collectionRole ); prepareForIndex( q ); } else { columns = currentColumns(); setType(); } //important!! continuation = false; }
public String[] toColumns(String alias, String propertyName) throws QueryException { //TODO: *two* hashmap lookups here is one too many... String[] columns = (String[]) columnsByPropertyPath.get(propertyName); if ( columns == null ) { throw propertyException( propertyName ); } String[] formulaTemplates = (String[]) formulaTemplatesByPropertyPath.get(propertyName); String[] columnReaderTemplates = (String[]) columnReaderTemplatesByPropertyPath.get(propertyName); String[] result = new String[columns.length]; for ( int i=0; i<columns.length; i++ ) { if ( columnReaderTemplates[i]==null ) { result[i] = StringHelper.replace( formulaTemplates[i], Template.TEMPLATE, alias ); } else { result[i] = StringHelper.replace( columnReaderTemplates[i], Template.TEMPLATE, alias ); } } return result; }
public String[] toColumns(String propertyName) throws QueryException { String[] columns = (String[]) columnsByPropertyPath.get(propertyName); if ( columns == null ) { throw propertyException( propertyName ); } String[] formulaTemplates = (String[]) formulaTemplatesByPropertyPath.get(propertyName); String[] columnReaders = (String[]) columnReadersByPropertyPath.get(propertyName); String[] result = new String[columns.length]; for ( int i=0; i<columns.length; i++ ) { if ( columnReaders[i]==null ) { result[i] = StringHelper.replace( formulaTemplates[i], Template.TEMPLATE, "" ); } else { result[i] = columnReaders[i]; } } return result; }
/** * Coordinates the efforts to perform a scroll across all the included query translators. * * @param queryParameters The query parameters * @param session The session * * @return The query result iterator * * @throws HibernateException Indicates a problem performing the query */ public ScrollableResults performScroll( QueryParameters queryParameters, SessionImplementor session) throws HibernateException { if ( TRACE_ENABLED ) { LOG.tracev( "Iterate: {0}", getSourceQuery() ); queryParameters.traceParameters( session.getFactory() ); } if ( translators.length != 1 ) { throw new QueryException( "implicit polymorphism not supported for scroll() queries" ); } if ( queryParameters.getRowSelection().definesLimits() && translators[0].containsCollectionFetches() ) { throw new QueryException( "firstResult/maxResults not supported in conjunction with scroll() of a query containing collection fetches" ); } return translators[0].scroll( queryParameters, session ); }
@Override public String render(Type firstArgumentType, List args, SessionFactoryImplementor factory) throws QueryException { final boolean threeArgs = args.size() > 2; final Object pattern = args.get( 0 ); final Object string = args.get( 1 ); final Object start = threeArgs ? args.get( 2 ) : null; final StringBuilder buf = new StringBuilder(); if (threeArgs) { buf.append( '(' ); } buf.append( "position(" ).append( pattern ).append( " in " ); if (threeArgs) { buf.append( "substring("); } buf.append( string ); if (threeArgs) { buf.append( ", " ).append( start ).append( ')' ); } buf.append( ')' ); if (threeArgs) { buf.append( '+' ).append( start ).append( "-1)" ); } return buf.toString(); }
private void createAssociationPathCriteriaMap() { final Iterator<CustomCriteriaImpl.Subcriteria> iter = rootCriteria.iterateSubcriteria(); while ( iter.hasNext() ) { CustomCriteriaImpl.Subcriteria crit = iter.next(); String wholeAssociationPath = getWholeAssociationPath( crit ); Object old = associationPathCriteriaMap.put( wholeAssociationPath, crit ); if ( old != null ) { throw new QueryException( "duplicate association path: " + wholeAssociationPath ); } JoinType joinType = crit.getJoinType(); old = associationPathJoinTypesMap.put( wholeAssociationPath, joinType ); if ( old != null ) { // TODO : not so sure this is needed... throw new QueryException( "duplicate association path: " + wholeAssociationPath ); } if ( crit.getWithClause() != null ) { this.withClauseMap.put( wholeAssociationPath, crit.getWithClause() ); } } }
private String getElementName(PathExpressionParser.CollectionElement element, QueryTranslatorImpl q) throws QueryException { String name; if ( element.isOneToMany ) { name = element.alias; } else { Type type = element.elementType; if ( type.isEntityType() ) { //ie. a many-to-many String entityName = ( ( EntityType ) type ).getAssociatedEntityName(); name = pathExpressionParser.continueFromManyToMany( entityName, element.elementColumns, q ); } else { throw new QueryException( "illegally dereferenced collection element" ); } } return name; }
@Override public String render(Type columnType, List args, SessionFactoryImplementor factory) throws QueryException { final boolean threeArgs = args.size() > 2; final Object pattern = args.get( 0 ); final Object string = args.get( 1 ); final Object start = threeArgs ? args.get( 2 ) : null; final StringBuilder buf = new StringBuilder(); buf.append( "charindex(" ).append( pattern ).append( ", " ); if (threeArgs) { buf.append( "right(" ); } buf.append( string ); if (threeArgs) { buf.append( ", char_length(" ).append( string ).append( ")-(" ).append( start ).append( "-1))" ); } buf.append( ')' ); return buf.toString(); }
@Override public String render(Type columnType, List args, SessionFactoryImplementor factory) throws QueryException { if ( args.size()!=2 ) { throw new QueryException( "cast() requires two arguments; found : " + args.size() ); } final String type = (String) args.get( 1 ); final int[] sqlTypeCodes = factory.getTypeResolver().heuristicType( type ).sqlTypes( factory ); if ( sqlTypeCodes.length!=1 ) { throw new QueryException("invalid Hibernate type for cast()"); } String sqlType = factory.getDialect().getCastTypeName( sqlTypeCodes[0] ); if ( sqlType == null ) { //TODO: never reached, since getExplicitHibernateTypeName() actually throws an exception! sqlType = type; } return "cast(" + args.get( 0 ) + " as " + sqlType + ')'; }
@Override public Type getReturnType(Type columnType, Mapping mapping) throws QueryException { int[] sqlTypes; try { sqlTypes = columnType.sqlTypes( mapping ); } catch ( MappingException me ) { throw new QueryException( me ); } if ( sqlTypes.length != 1 ) { throw new QueryException( "multi-column type in avg()" ); } final int sqlType = sqlTypes[0]; if ( sqlType == Types.INTEGER || sqlType == Types.BIGINT || sqlType == Types.TINYINT ) { return StandardBasicTypes.FLOAT; } else { return columnType; } }
/** * Locate the collection persister by the collection role, requiring that * such a persister exist. * * @param role The collection role name. * * @return The defined CollectionPersister for this collection role. * * @throws QueryException Indicates that the collection persister could not be found. */ public QueryableCollection requireQueryableCollection(String role) throws QueryException { try { QueryableCollection queryableCollection = (QueryableCollection) sfi.getCollectionPersister( role ); if ( queryableCollection != null ) { collectionPropertyMappingByRole.put( role, new CollectionPropertyMapping( queryableCollection ) ); } return queryableCollection; } catch ( ClassCastException cce ) { throw new QueryException( "collection role is not queryable: " + role ); } catch ( Exception e ) { throw new QueryException( "collection role not found: " + role ); } }
/** * Returns the locations of all occurrences of the named parameter. */ public int[] getNamedParameterLocations(String name) throws QueryException { Object o = namedParameters.get( name ); if ( o == null ) { throw new QueryException( QueryTranslator.ERROR_NAMED_PARAMETER_DOES_NOT_APPEAR + name, queryTranslatorImpl.getQueryString() ); } if ( o instanceof Integer ) { return new int[] {(Integer) o}; } else { return ArrayHelper.toIntArray( (ArrayList) o ); } }
public void validateTypes(SelectClause selectClause) throws QueryException { Type[] selectTypes = selectClause.getQueryReturnTypes(); if ( selectTypes.length + selectClause.getTotalParameterCount() != types.length ) { throw new QueryException( "number of select types did not match those for insert" ); } int parameterCount = 0; for ( int i = 0; i < types.length; i++ ) { if( selectClause.getParameterPositions().contains(i) ) { parameterCount++; } else if ( !areCompatible( types[i], selectTypes[i - parameterCount] ) ) { throw new QueryException( "insertion type [" + types[i] + "] and selection type [" + selectTypes[i - parameterCount] + "] at position " + i + " are not compatible" ); } } // otherwise, everything ok. }
PropertyMapping getPropertyMapping(String name) throws QueryException { PropertyMapping decorator = getDecoratedPropertyMapping( name ); if ( decorator != null ) return decorator; String type = getType( name ); if ( type == null ) { String role = getRole( name ); if ( role == null ) { throw new QueryException( "alias not found: " + name ); } return getCollectionPersister( role ); //.getElementPropertyMapping(); } else { Queryable persister = getEntityPersister( type ); if ( persister == null ) throw new QueryException( "persistent class not found: " + type ); return persister; } }
void setCollectionToFetch(String role, String name, String ownerName, String entityName) throws QueryException { fetchName = name; collectionPersister = getCollectionPersister( role ); collectionOwnerName = ownerName; if ( collectionPersister.getElementType().isEntityType() ) { addEntityToFetch( entityName ); } }
/** * Wrap the incoming tuples in a call to our configured constructor. */ @Override public Object transformTuple(Object[] tuple, String[] aliases) { try { return constructor.newInstance( tuple ); } catch ( Exception e ) { throw new QueryException( "could not instantiate class [" + constructor.getDeclaringClass().getName() + "] from tuple", e ); } }
private void createAliasCriteriaMap() { aliasCriteriaMap.put( rootCriteria.getAlias(), rootCriteria ); Iterator<CriteriaImpl.Subcriteria> iter = rootCriteria.iterateSubcriteria(); while ( iter.hasNext() ) { Criteria subcriteria = iter.next(); if ( subcriteria.getAlias() != null ) { Object old = aliasCriteriaMap.put( subcriteria.getAlias(), subcriteria ); if ( old != null ) { throw new QueryException( "duplicate alias: " + subcriteria.getAlias() ); } } } }
@Override public void betweenFunctionArguments() { if ( startedType ) { throw new QueryException( "CAST function should only have 2 arguments" ); } startedType = true; }
/** * Get the a typed value for the given property value. */ @Override public TypedValue getTypedValue(Criteria subcriteria, String propertyName, Object value) throws HibernateException { // Detect discriminator values... if ( value instanceof Class ) { final Class entityClass = (Class) value; final Queryable q = SessionFactoryHelper.findQueryableUsingImports( sessionFactory, entityClass.getName() ); if ( q != null ) { final Type type = q.getDiscriminatorType(); String stringValue = q.getDiscriminatorSQLValue(); if ( stringValue != null && stringValue.length() > 2 && stringValue.startsWith( "'" ) && stringValue.endsWith( "'" ) ) { // remove the single quotes stringValue = stringValue.substring( 1, stringValue.length() - 1 ); } // Convert the string value into the proper type. if ( type instanceof StringRepresentableType ) { final StringRepresentableType nullableType = (StringRepresentableType) type; value = nullableType.fromStringValue( stringValue ); } else { throw new QueryException( "Unsupported discriminator type " + type ); } return new TypedValue( type, value ); } } // Otherwise, this is an ordinary value. return new TypedValue( getTypeUsingProjection( subcriteria, propertyName ), value ); }
@Override protected String applyLocks( String sql, QueryParameters parameters, Dialect dialect, List<AfterLoadAction> afterLoadActions) throws QueryException { final LockOptions lockOptions = parameters.getLockOptions(); if ( lockOptions == null || ( lockOptions.getLockMode() == LockMode.NONE && lockOptions.getAliasLockCount() == 0 ) ) { return sql; } // user is request locking, lets see if we can apply locking directly to the SQL... // some dialects wont allow locking with paging... afterLoadActions.add( new AfterLoadAction() { private final LockOptions originalLockOptions = lockOptions.makeCopy(); @Override public void afterLoad(SessionImplementor session, Object entity, Loadable persister) { ( (Session) session ).buildLockRequest( originalLockOptions ).lock( persister.getEntityName(), entity ); } } ); parameters.getLockOptions().setLockMode( LockMode.READ ); return sql; }
/** * Returns the identifier select SQL fragment. * * @param size The total number of returned types. * @param k The sequence of the current returned type. * * @return the identifier select SQL fragment. */ String renderIdentifierSelect(int size, int k) { checkInitialized(); // Render the identifier select fragment using the table alias. if ( fromElement.getFromClause().isSubQuery() ) { // TODO: Replace this with a more elegant solution. String[] idColumnNames = ( persister != null ) ? ( (Queryable) persister ).getIdentifierColumnNames() : new String[0]; StringBuilder buf = new StringBuilder(); for ( int i = 0; i < idColumnNames.length; i++ ) { buf.append( fromElement.getTableAlias() ).append( '.' ).append( idColumnNames[i] ); if ( i != idColumnNames.length - 1 ) { buf.append( ", " ); } } return buf.toString(); } else { if ( persister == null ) { throw new QueryException( "not an entity" ); } String fragment = ( (Queryable) persister ).identifierSelectFragment( getTableAlias(), getSuffix( size, k ) ); return trimLeadingCommaAndSpaces( fragment ); } }
@Override public Type getDataType() { // option is used to hold each WHEN/ELSE in turn AST option = getFirstChild(); while ( option != null ) { final AST result; if ( option.getType() == HqlSqlTokenTypes.WHEN ) { result = option.getFirstChild().getNextSibling(); } else if ( option.getType() == HqlSqlTokenTypes.ELSE ) { result = option.getFirstChild(); } else { throw new QueryException( "Unexpected node type :" + ASTUtil.getTokenTypeName( HqlSqlTokenTypes.class, option.getType() ) + "; expecting WHEN or ELSE" ); } if ( SqlNode.class.isInstance( result ) ) { final Type nodeDataType = ( (SqlNode) result ).getDataType(); if ( nodeDataType != null ) { return nodeDataType; } } option = option.getNextSibling(); } throw new QueryException( "Could not determine data type for searched case statement" ); }
private void doPathExpression(String token, QueryTranslatorImpl q) throws QueryException { preprocess( token, q ); StringTokenizer tokens = new StringTokenizer( token, ".", true ); pathExpressionParser.start( q ); while ( tokens.hasMoreTokens() ) { pathExpressionParser.token( tokens.nextToken(), q ); } pathExpressionParser.end( q ); if ( pathExpressionParser.isCollectionValued() ) { openExpression( q, "" ); appendToken( q, pathExpressionParser.getCollectionSubquery( q.getEnabledFilters() ) ); closeExpression( q, "" ); // this is ugly here, but needed because its a subquery q.addQuerySpaces( q.getCollectionPersister( pathExpressionParser.getCollectionRole() ).getCollectionSpaces() ); } else { if ( pathExpressionParser.isExpectingCollectionIndex() ) { expectingIndex++; } else { addJoin( pathExpressionParser.getWhereJoin(), q ); appendToken( q, pathExpressionParser.getWhereColumn() ); } } }
QueryableCollection getCollectionPersister(String role) throws QueryException { try { return ( QueryableCollection ) getFactory().getCollectionPersister( role ); } catch ( ClassCastException cce ) { throw new QueryException( "collection role is not queryable: " + role ); } catch ( Exception e ) { throw new QueryException( "collection role not found: " + role ); } }
public Type toType(String propertyName) throws QueryException { Type type = (Type) typesByPropertyPath.get(propertyName); if ( type == null ) { throw propertyException( propertyName ); } return type; }
/** * Used for collection filters */ private void addFromAssociation(final String elementName, final String collectionRole) throws QueryException { //q.addCollection(collectionName, collectionRole); QueryableCollection persister = getCollectionPersister( collectionRole ); Type collectionElementType = persister.getElementType(); if ( !collectionElementType.isEntityType() ) { throw new QueryException( "collection of values in filter: " + elementName ); } String[] keyColumnNames = persister.getKeyColumnNames(); //if (keyColumnNames.length!=1) throw new QueryException("composite-key collection in filter: " + collectionRole); String collectionName; JoinSequence join = new JoinSequence( getFactory() ); collectionName = persister.isOneToMany() ? elementName : createNameForCollection( collectionRole ); join.setRoot( persister, collectionName ); if ( !persister.isOneToMany() ) { //many-to-many addCollection( collectionName, collectionRole ); try { join.addJoin( ( AssociationType ) persister.getElementType(), elementName, JoinType.INNER_JOIN, persister.getElementColumnNames(collectionName) ); } catch ( MappingException me ) { throw new QueryException( me ); } } join.addCondition( collectionName, keyColumnNames, " = ?" ); //if ( persister.hasWhere() ) join.addCondition( persister.getSQLWhereString(collectionName) ); EntityType elemType = ( EntityType ) collectionElementType; addFrom( elementName, elemType.getAssociatedEntityName(), join ); }
public Type toType(String propertyName) throws QueryException { if ( propertyName==null || "id".equals(propertyName) ) { return type; } else { throw new QueryException("cannot dereference scalar collection element: " + propertyName); } }
public String[] toColumns(String alias, String propertyName) throws QueryException { if (propertyName==null || "id".equals(propertyName) ) { return StringHelper.qualify( alias, elementColumns ); } else { throw new QueryException("cannot dereference scalar collection element: " + propertyName); } }
@Override public String[] toColumns(String alias, String propertyName) throws QueryException { if ( "index".equals( propertyName ) ) { return qualify( alias, indexColumnNames, indexFormulaTemplates ); } return elementPropertyMapping.toColumns( alias, propertyName ); }
public String addFromCollection(QueryTranslatorImpl q) throws QueryException { Type collectionElementType = getPropertyType(); if ( collectionElementType == null ) { throw new QueryException( "must specify 'elements' for collection valued property in from clause: " + path ); } if ( collectionElementType.isEntityType() ) { // an association QueryableCollection collectionPersister = q.getCollectionPersister( collectionRole ); Queryable entityPersister = ( Queryable ) collectionPersister.getElementPersister(); String clazz = entityPersister.getEntityName(); final String elementName; if ( collectionPersister.isOneToMany() ) { elementName = collectionName; //allow index() function: q.decoratePropertyMapping( elementName, collectionPersister ); } else { //many-to-many q.addCollection( collectionName, collectionRole ); elementName = q.createNameFor( clazz ); addJoin( elementName, ( AssociationType ) collectionElementType ); } q.addFrom( elementName, clazz, joinSequence ); currentPropertyMapping = new CollectionPropertyMapping( collectionPersister ); return elementName; } else { // collections of values q.addFromCollection( collectionName, collectionRole, joinSequence ); return collectionName; } }
public static String createCollectionSubquery( JoinSequence joinSequence, Map enabledFilters, String[] columns) { try { JoinFragment join = joinSequence.toJoinFragment( enabledFilters, true ); return "select " + StringHelper.join( ", ", columns ) + " from " + join.toFromFragmentString().substring( 2 ) + " where " + join.toWhereFragmentString().substring( 5 ); } catch (MappingException me) { throw new QueryException( me ); } }
/** * Get the query plan for the given HQL query, creating it and caching it if not already cached * * @param queryString The HQL query string * @param shallow Whether the execution will be shallow * @param enabledFilters The filters enabled on the Session * * @return The query plan * * @throws QueryException Indicates a problem translating the query * @throws MappingException Indicates a problem translating the query */ @SuppressWarnings("unchecked") public HQLQueryPlan getHQLQueryPlan(String queryString, boolean shallow, Map<String,Filter> enabledFilters) throws QueryException, MappingException { final HQLQueryPlanKey key = new HQLQueryPlanKey( queryString, shallow, enabledFilters ); HQLQueryPlan value = (HQLQueryPlan) queryPlanCache.get( key ); if ( value == null ) { LOG.tracev( "Unable to locate HQL query plan in cache; generating ({0})", queryString ); value = new HQLQueryPlan( queryString, shallow, enabledFilters, factory ); queryPlanCache.putIfAbsent( key, value ); } else { LOG.tracev( "Located HQL query plan in cache ({0})", queryString ); } return value; }
private void mergeJoins(JoinFragment ojf) throws MappingException, QueryException { Iterator iter = joins.entrySet().iterator(); while ( iter.hasNext() ) { Map.Entry me = ( Map.Entry ) iter.next(); String name = ( String ) me.getKey(); JoinSequence join = ( JoinSequence ) me.getValue(); join.setSelector( new JoinSequence.Selector() { public boolean includeSubclasses(String alias) { boolean include = returnedTypes.contains( alias ) && !isShallowQuery(); return include; } } ); if ( typeMap.containsKey( name ) ) { ojf.addFragment( join.toJoinFragment( enabledFilters, true ) ); } else if ( collections.containsKey( name ) ) { ojf.addFragment( join.toJoinFragment( enabledFilters, true ) ); } else { //name from a super query (a bit inelegant that it shows up here) } } }
private void createAliasCriteriaMap() { aliasCriteriaMap.put( rootCriteria.getAlias(), rootCriteria ); Iterator<CustomCriteriaImpl.Subcriteria> iter = rootCriteria.iterateSubcriteria(); while ( iter.hasNext() ) { Criteria subcriteria = iter.next(); if ( subcriteria.getAlias() != null ) { Object old = aliasCriteriaMap.put( subcriteria.getAlias(), subcriteria ); if ( old != null ) { throw new QueryException( "duplicate alias: " + subcriteria.getAlias() ); } } } }
public Query setParameterList(String name, Collection vals) throws HibernateException { if ( vals == null ) { throw new QueryException( "Collection must be not null!" ); } if( vals.size() == 0 ) { setParameterList( name, vals, null ); } else { setParameterList(name, vals, determineType( name, vals.iterator().next() ) ); } return this; }
public void end(QueryTranslatorImpl q) throws QueryException { if ( expectingPathContinuation ) { expectingPathContinuation = false; PathExpressionParser.CollectionElement element = pathExpressionParser.lastCollectionElement(); if ( element.elementColumns.length != 1 ) throw new QueryException( "path expression ended in composite collection element" ); appendToken( q, element.elementColumns[0] ); addToCurrentJoin( element ); } token( ")", q ); }