use of org.hibernate.QueryException in project hibernate-orm by hibernate.
the class AbstractEmptinessExpression method getQueryableCollection.
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);
}
}
use of org.hibernate.QueryException in project hibernate-orm by hibernate.
the class ParameterParser method parse.
/**
* Performs the actual parsing and tokenizing of the query string making appropriate
* callbacks to the given recognizer upon recognition of the various tokens.
* <p/>
* Note that currently, this only knows how to deal with a single output
* parameter (for callable statements). If we later add support for
* multiple output params, this, obviously, needs to change.
*
* @param sqlString The string to be parsed/tokenized.
* @param recognizer The thing which handles recognition events.
* @throws QueryException Indicates unexpected parameter conditions.
*/
public static void parse(String sqlString, Recognizer recognizer) throws QueryException {
final boolean hasMainOutputParameter = startsWithEscapeCallTemplate(sqlString);
boolean foundMainOutputParam = false;
final int stringLength = sqlString.length();
boolean inSingleQuotes = false;
boolean inDoubleQuotes = false;
boolean inLineComment = false;
boolean inDelimitedComment = false;
for (int indx = 0; indx < stringLength; indx++) {
final char c = sqlString.charAt(indx);
final boolean lastCharacter = indx == stringLength - 1;
// if we are "in" a certain context, check first for the end of that context
if (inSingleQuotes) {
recognizer.other(c);
if ('\'' == c) {
inSingleQuotes = false;
}
} else if (inDoubleQuotes) {
recognizer.other(c);
if ('\"' == c) {
inDoubleQuotes = false;
}
} else if (inDelimitedComment) {
recognizer.other(c);
if (!lastCharacter && '*' == c && '/' == sqlString.charAt(indx + 1)) {
inDelimitedComment = false;
recognizer.other(sqlString.charAt(indx + 1));
indx++;
}
} else if (inLineComment) {
recognizer.other(c);
// see if the character ends the line
if ('\n' == c) {
inLineComment = false;
} else if ('\r' == c) {
inLineComment = false;
if (!lastCharacter && '\n' == sqlString.charAt(indx + 1)) {
recognizer.other(sqlString.charAt(indx + 1));
indx++;
}
}
} else // otherwise, see if we start such a context
if (!lastCharacter && '/' == c && '*' == sqlString.charAt(indx + 1)) {
inDelimitedComment = true;
recognizer.other(c);
recognizer.other(sqlString.charAt(indx + 1));
indx++;
} else if ('-' == c) {
recognizer.other(c);
if (!lastCharacter && '-' == sqlString.charAt(indx + 1)) {
inLineComment = true;
recognizer.other(sqlString.charAt(indx + 1));
indx++;
}
} else if ('\"' == c) {
inDoubleQuotes = true;
recognizer.other(c);
} else if ('\'' == c) {
inSingleQuotes = true;
recognizer.other(c);
} else // special handling for backslash
if ('\\' == c) {
// skip sending the backslash and instead send then next character, treating is as a literal
recognizer.other(sqlString.charAt(++indx));
} else // otherwise
{
if (c == ':' && indx < stringLength - 1 && sqlString.charAt(indx + 1) == ':') {
// colon character has been escaped
recognizer.other(c);
indx++;
} else if (c == ':') {
// named parameter
final int right = StringHelper.firstIndexOfChar(sqlString, ParserHelper.HQL_SEPARATORS_BITSET, indx + 1);
final int chopLocation = right < 0 ? sqlString.length() : right;
final String param = sqlString.substring(indx + 1, chopLocation);
if (StringHelper.isEmpty(param)) {
throw new QueryException("Space is not allowed afterQuery parameter prefix ':' [" + sqlString + "]");
}
recognizer.namedParameter(param, indx);
indx = chopLocation - 1;
} else if (c == '?') {
// could be either an ordinal or JPA-positional parameter
if (indx < stringLength - 1 && Character.isDigit(sqlString.charAt(indx + 1))) {
// a peek ahead showed this as an JPA-positional parameter
final int right = StringHelper.firstIndexOfChar(sqlString, ParserHelper.HQL_SEPARATORS, indx + 1);
final int chopLocation = right < 0 ? sqlString.length() : right;
final String param = sqlString.substring(indx + 1, chopLocation);
// make sure this "name" is an integral
try {
Integer.valueOf(param);
} catch (NumberFormatException e) {
throw new QueryException("JPA-style positional param was not an integral ordinal");
}
recognizer.jpaPositionalParameter(param, indx);
indx = chopLocation - 1;
} else {
if (hasMainOutputParameter && !foundMainOutputParam) {
foundMainOutputParam = true;
recognizer.outParameter(indx);
} else {
recognizer.ordinalParameter(indx);
}
}
} else {
recognizer.other(c);
}
}
}
}
use of org.hibernate.QueryException in project hibernate-orm by hibernate.
the class HqlSqlWalker method prepareFromClauseInputTree.
@Override
protected void prepareFromClauseInputTree(AST fromClauseInput) {
if (!isSubQuery()) {
if (isFilter()) {
// Handle collection-filter compilation.
// IMPORTANT NOTE: This is modifying the INPUT (HQL) tree, not the output tree!
QueryableCollection persister = sessionFactoryHelper.getCollectionPersister(collectionFilterRole);
Type collectionElementType = persister.getElementType();
if (!collectionElementType.isEntityType()) {
throw new QueryException("collection of values in filter: this");
}
String collectionElementEntityName = persister.getElementPersister().getEntityName();
ASTFactory inputAstFactory = hqlParser.getASTFactory();
AST fromElement = inputAstFactory.create(HqlTokenTypes.FILTER_ENTITY, collectionElementEntityName);
ASTUtil.createSibling(inputAstFactory, HqlTokenTypes.ALIAS, "this", fromElement);
fromClauseInput.addChild(fromElement);
// Show the modified AST.
LOG.debug("prepareFromClauseInputTree() : Filter - Added 'this' as a from element...");
queryTranslatorImpl.showHqlAst(hqlParser.getAST());
// Create a parameter specification for the collection filter...
Type collectionFilterKeyType = sessionFactoryHelper.requireQueryableCollection(collectionFilterRole).getKeyType();
ParameterNode collectionFilterKeyParameter = (ParameterNode) astFactory.create(PARAM, "?");
CollectionFilterKeyParameterSpecification collectionFilterKeyParameterSpec = new CollectionFilterKeyParameterSpecification(collectionFilterRole, collectionFilterKeyType, positionalParameterCount++);
collectionFilterKeyParameter.setHqlParameterSpecification(collectionFilterKeyParameterSpec);
parameters.add(collectionFilterKeyParameterSpec);
}
}
}
use of org.hibernate.QueryException in project hibernate-orm by hibernate.
the class HqlSqlWalker method postProcessInsert.
@Override
protected void postProcessInsert(AST insert) throws SemanticException, QueryException {
InsertStatement insertStatement = (InsertStatement) insert;
insertStatement.validate();
SelectClause selectClause = insertStatement.getSelectClause();
Queryable persister = insertStatement.getIntoClause().getQueryable();
if (!insertStatement.getIntoClause().isExplicitIdInsertion()) {
// the insert did not explicitly reference the id. See if
// 1) that is allowed
// 2) whether we need to alter the SQL tree to account for id
final IdentifierGenerator generator = persister.getIdentifierGenerator();
if (!BulkInsertionCapableIdentifierGenerator.class.isInstance(generator)) {
throw new QueryException("Invalid identifier generator encountered for implicit id handling as part of bulk insertions");
}
final BulkInsertionCapableIdentifierGenerator capableGenerator = BulkInsertionCapableIdentifierGenerator.class.cast(generator);
if (!capableGenerator.supportsBulkInsertionIdentifierGeneration()) {
throw new QueryException("Identifier generator reported it does not support implicit id handling as part of bulk insertions");
}
final String fragment = capableGenerator.determineBulkInsertionIdentifierGenerationSelectFragment(sessionFactoryHelper.getFactory().getDialect());
if (fragment != null) {
// we got a fragment from the generator, so alter the sql tree...
//
// first, wrap the fragment as a node
AST fragmentNode = getASTFactory().create(HqlSqlTokenTypes.SQL_TOKEN, fragment);
// next, rearrange the SQL tree to add the fragment node as the first select expression
AST originalFirstSelectExprNode = selectClause.getFirstChild();
selectClause.setFirstChild(fragmentNode);
fragmentNode.setNextSibling(originalFirstSelectExprNode);
// finally, prepend the id column name(s) to the insert-spec
insertStatement.getIntoClause().prependIdColumnSpec();
}
}
if (sessionFactoryHelper.getFactory().getDialect().supportsParametersInInsertSelect()) {
AST child = selectClause.getFirstChild();
int i = 0;
while (child != null) {
if (child instanceof ParameterNode) {
// infer the parameter type from the type listed in the INSERT INTO clause
((ParameterNode) child).setExpectedType(insertStatement.getIntoClause().getInsertionTypes()[selectClause.getParameterPositions().get(i)]);
i++;
}
child = child.getNextSibling();
}
}
final boolean includeVersionProperty = persister.isVersioned() && !insertStatement.getIntoClause().isExplicitVersionInsertion() && persister.isVersionPropertyInsertable();
if (includeVersionProperty) {
// We need to seed the version value as part of this bulk insert
VersionType versionType = persister.getVersionType();
AST versionValueNode = null;
if (sessionFactoryHelper.getFactory().getDialect().supportsParametersInInsertSelect()) {
int[] sqlTypes = versionType.sqlTypes(sessionFactoryHelper.getFactory());
if (sqlTypes == null || sqlTypes.length == 0) {
throw new IllegalStateException(versionType.getClass() + ".sqlTypes() returns null or empty array");
}
if (sqlTypes.length > 1) {
throw new IllegalStateException(versionType.getClass() + ".sqlTypes() returns > 1 element; only single-valued versions are allowed.");
}
versionValueNode = getASTFactory().create(HqlSqlTokenTypes.PARAM, "?");
ParameterSpecification paramSpec = new VersionTypeSeedParameterSpecification(versionType);
((ParameterNode) versionValueNode).setHqlParameterSpecification(paramSpec);
parameters.add(0, paramSpec);
if (sessionFactoryHelper.getFactory().getDialect().requiresCastingOfParametersInSelectClause()) {
// we need to wrtap the param in a cast()
MethodNode versionMethodNode = (MethodNode) getASTFactory().create(HqlSqlTokenTypes.METHOD_CALL, "(");
AST methodIdentNode = getASTFactory().create(HqlSqlTokenTypes.IDENT, "cast");
versionMethodNode.addChild(methodIdentNode);
versionMethodNode.initializeMethodNode(methodIdentNode, true);
AST castExprListNode = getASTFactory().create(HqlSqlTokenTypes.EXPR_LIST, "exprList");
methodIdentNode.setNextSibling(castExprListNode);
castExprListNode.addChild(versionValueNode);
versionValueNode.setNextSibling(getASTFactory().create(HqlSqlTokenTypes.IDENT, sessionFactoryHelper.getFactory().getDialect().getTypeName(sqlTypes[0])));
processFunction(versionMethodNode, true);
versionValueNode = versionMethodNode;
}
} else {
if (isIntegral(versionType)) {
try {
Object seedValue = versionType.seed(null);
versionValueNode = getASTFactory().create(HqlSqlTokenTypes.SQL_TOKEN, seedValue.toString());
} catch (Throwable t) {
throw new QueryException("could not determine seed value for version on bulk insert [" + versionType + "]");
}
} else if (isDatabaseGeneratedTimestamp(versionType)) {
String functionName = sessionFactoryHelper.getFactory().getDialect().getCurrentTimestampSQLFunctionName();
versionValueNode = getASTFactory().create(HqlSqlTokenTypes.SQL_TOKEN, functionName);
} else {
throw new QueryException("cannot handle version type [" + versionType + "] on bulk inserts with dialects not supporting parameters in insert-select statements");
}
}
AST currentFirstSelectExprNode = selectClause.getFirstChild();
selectClause.setFirstChild(versionValueNode);
versionValueNode.setNextSibling(currentFirstSelectExprNode);
insertStatement.getIntoClause().prependVersionColumnSpec();
}
if (insertStatement.getIntoClause().isDiscriminated()) {
String sqlValue = insertStatement.getIntoClause().getQueryable().getDiscriminatorSQLValue();
AST discrimValue = getASTFactory().create(HqlSqlTokenTypes.SQL_TOKEN, sqlValue);
insertStatement.getSelectClause().addChild(discrimValue);
}
}
use of org.hibernate.QueryException in project hibernate-orm by hibernate.
the class FromElement method handlePropertyBeingDereferenced.
public void handlePropertyBeingDereferenced(Type propertySource, String propertyName) {
if (getQueryableCollection() != null && CollectionProperties.isCollectionProperty(propertyName)) {
// propertyName refers to something like collection.size...
return;
}
if (propertySource.isComponentType()) {
// property name is a sub-path of a component...
return;
}
Queryable persister = getQueryable();
if (persister != null) {
try {
Queryable.Declarer propertyDeclarer = persister.getSubclassPropertyDeclarer(propertyName);
if (LOG.isTraceEnabled()) {
LOG.tracev("Handling property dereference [{0} ({1}) -> {2} ({3})]", persister.getEntityName(), getClassAlias(), propertyName, propertyDeclarer);
}
if (propertyDeclarer == Queryable.Declarer.SUBCLASS) {
dereferencedBySubclassProperty = true;
includeSubclasses = true;
} else if (propertyDeclarer == Queryable.Declarer.SUPERCLASS) {
dereferencedBySuperclassProperty = true;
}
} catch (QueryException ignore) {
// ignore it; the incoming property could not be found so we
// cannot be sure what to do here. At the very least, the
// safest is to simply not apply any dereference toggling...
}
}
}
Aggregations