use of org.hibernate.query.SemanticException in project hibernate-orm by hibernate.
the class SemanticQueryBuilder method visitQueryOrder.
protected void visitQueryOrder(SqmQueryPart<?> sqmQueryPart, HqlParser.QueryOrderContext ctx) {
if (ctx == null) {
return;
}
final SqmOrderByClause orderByClause;
final HqlParser.OrderByClauseContext orderByClauseContext = (HqlParser.OrderByClauseContext) ctx.getChild(0);
if (orderByClauseContext != null) {
if (creationOptions.useStrictJpaCompliance() && processingStateStack.depth() > 1) {
throw new StrictJpaComplianceViolation(StrictJpaComplianceViolation.Type.SUBQUERY_ORDER_BY);
}
orderByClause = visitOrderByClause(orderByClauseContext);
sqmQueryPart.setOrderByClause(orderByClause);
} else {
orderByClause = null;
}
int currentIndex = 1;
final HqlParser.LimitClauseContext limitClauseContext;
if (currentIndex < ctx.getChildCount() && ctx.getChild(currentIndex) instanceof HqlParser.LimitClauseContext) {
limitClauseContext = (HqlParser.LimitClauseContext) ctx.getChild(currentIndex++);
} else {
limitClauseContext = null;
}
final HqlParser.OffsetClauseContext offsetClauseContext;
if (currentIndex < ctx.getChildCount() && ctx.getChild(currentIndex) instanceof HqlParser.OffsetClauseContext) {
offsetClauseContext = (HqlParser.OffsetClauseContext) ctx.getChild(currentIndex++);
} else {
offsetClauseContext = null;
}
final HqlParser.FetchClauseContext fetchClauseContext;
if (currentIndex < ctx.getChildCount() && ctx.getChild(currentIndex) instanceof HqlParser.FetchClauseContext) {
fetchClauseContext = (HqlParser.FetchClauseContext) ctx.getChild(currentIndex++);
} else {
fetchClauseContext = null;
}
if (currentIndex != 1) {
if (getCreationOptions().useStrictJpaCompliance()) {
throw new StrictJpaComplianceViolation(StrictJpaComplianceViolation.Type.LIMIT_OFFSET_CLAUSE);
}
if (processingStateStack.depth() > 1 && orderByClause == null) {
throw new SemanticException("limit, offset and fetch clause require an order-by clause when used in sub-query");
}
sqmQueryPart.setOffsetExpression(visitOffsetClause(offsetClauseContext));
if (limitClauseContext == null) {
sqmQueryPart.setFetchExpression(visitFetchClause(fetchClauseContext), visitFetchClauseType(fetchClauseContext));
} else if (fetchClauseContext == null) {
sqmQueryPart.setFetchExpression(visitLimitClause(limitClauseContext));
} else {
throw new SemanticException("Can't use both limit and fetch clause");
}
}
}
use of org.hibernate.query.SemanticException in project hibernate-orm by hibernate.
the class SemanticQueryBuilder method visitUpdateStatement.
@Override
public SqmUpdateStatement<R> visitUpdateStatement(HqlParser.UpdateStatementContext ctx) {
final boolean versioned = !(ctx.getChild(1) instanceof HqlParser.TargetEntityContext);
final int dmlTargetIndex = versioned ? 2 : 1;
final HqlParser.TargetEntityContext dmlTargetContext = (HqlParser.TargetEntityContext) ctx.getChild(dmlTargetIndex);
final SqmRoot<R> root = visitTargetEntity(dmlTargetContext);
if (root.getReferencedPathSource() instanceof SqmPolymorphicRootDescriptor<?>) {
throw new SemanticException(String.format("Target type '%s' in update statement is not an entity", root.getReferencedPathSource().getHibernateEntityName()));
}
final SqmUpdateStatement<R> updateStatement = new SqmUpdateStatement<>(root, creationContext.getNodeBuilder());
parameterCollector = updateStatement;
final SqmDmlCreationProcessingState processingState = new SqmDmlCreationProcessingState(updateStatement, this);
processingStateStack.push(processingState);
processingState.getPathRegistry().register(root);
try {
updateStatement.versioned(versioned);
final HqlParser.SetClauseContext setClauseCtx = (HqlParser.SetClauseContext) ctx.getChild(dmlTargetIndex + 1);
for (ParseTree subCtx : setClauseCtx.children) {
if (subCtx instanceof HqlParser.AssignmentContext) {
final HqlParser.AssignmentContext assignmentContext = (HqlParser.AssignmentContext) subCtx;
updateStatement.applyAssignment(consumeDomainPath((HqlParser.SimplePathContext) assignmentContext.getChild(0)), (SqmExpression<?>) assignmentContext.getChild(2).accept(this));
}
}
if (dmlTargetIndex + 2 <= ctx.getChildCount()) {
updateStatement.applyPredicate(visitWhereClause((HqlParser.WhereClauseContext) ctx.getChild(dmlTargetIndex + 2)));
}
return updateStatement;
} finally {
processingStateStack.pop();
}
}
use of org.hibernate.query.SemanticException in project hibernate-orm by hibernate.
the class SemanticQueryBuilder method visitEntityNaturalIdReference.
@Override
public SqmPath<?> visitEntityNaturalIdReference(HqlParser.EntityNaturalIdReferenceContext ctx) {
final SqmPath<Object> sqmPath = consumeDomainPath((HqlParser.PathContext) ctx.getChild(2));
final DomainType<?> sqmPathType = sqmPath.getReferencedPathSource().getSqmPathType();
if (sqmPathType instanceof IdentifiableDomainType<?>) {
@SuppressWarnings("unchecked") final IdentifiableDomainType<Object> identifiableType = (IdentifiableDomainType<? super Object>) sqmPathType;
final List<? extends PersistentAttribute<Object, ?>> attributes = identifiableType.findNaturalIdAttributes();
if (attributes == null) {
throw new SemanticException(String.format("Path '%s' resolved to entity type '%s' which does not define a natural id", sqmPath.getNavigablePath().getFullPath(), identifiableType.getTypeName()));
} else if (attributes.size() > 1) {
throw new SemanticException(String.format("Path '%s' resolved to entity type '%s' which defines multiple natural ids", sqmPath.getNavigablePath().getFullPath(), identifiableType.getTypeName()));
}
@SuppressWarnings("unchecked") SingularAttribute<Object, ?> naturalIdAttribute = (SingularAttribute<Object, ?>) attributes.get(0);
return sqmPath.get(naturalIdAttribute);
}
throw new SemanticException("Path does not resolve to an entity type '" + sqmPath.getNavigablePath().getFullPath() + "'");
}
use of org.hibernate.query.SemanticException in project hibernate-orm by hibernate.
the class SemanticQueryBuilder method visitInstantiation.
@Override
public SqmDynamicInstantiation<?> visitInstantiation(HqlParser.InstantiationContext ctx) {
final SqmDynamicInstantiation<?> dynamicInstantiation;
final ParseTree instantiationTarget = ctx.instantiationTarget().getChild(0);
if (instantiationTarget instanceof HqlParser.SimplePathContext) {
final String className = instantiationTarget.getText();
try {
final JavaType<?> jtd = resolveInstantiationTargetJtd(className);
dynamicInstantiation = SqmDynamicInstantiation.forClassInstantiation(jtd, creationContext.getNodeBuilder());
} catch (ClassLoadingException e) {
throw new SemanticException("Could not resolve class '" + className + "' named for instantiation");
}
} else {
final TerminalNode terminalNode = (TerminalNode) instantiationTarget;
switch(terminalNode.getSymbol().getType()) {
case HqlParser.MAP:
dynamicInstantiation = SqmDynamicInstantiation.forMapInstantiation(mapJavaType, creationContext.getNodeBuilder());
break;
case HqlParser.LIST:
dynamicInstantiation = SqmDynamicInstantiation.forListInstantiation(listJavaType, creationContext.getNodeBuilder());
break;
default:
throw new UnsupportedOperationException("Unsupported instantiation target: " + terminalNode);
}
}
for (HqlParser.InstantiationArgumentContext arg : ctx.instantiationArguments().instantiationArgument()) {
dynamicInstantiation.addArgument(visitInstantiationArgument(arg));
}
return dynamicInstantiation;
}
use of org.hibernate.query.SemanticException in project hibernate-orm by hibernate.
the class SemanticQueryBuilder method visitInsertStatement.
@Override
public SqmInsertStatement<R> visitInsertStatement(HqlParser.InsertStatementContext ctx) {
final int dmlTargetIndex;
if (ctx.getChild(1) instanceof HqlParser.TargetEntityContext) {
dmlTargetIndex = 1;
} else {
dmlTargetIndex = 2;
}
final HqlParser.TargetEntityContext dmlTargetContext = (HqlParser.TargetEntityContext) ctx.getChild(dmlTargetIndex);
final HqlParser.TargetFieldsContext targetFieldsSpecContext = (HqlParser.TargetFieldsContext) ctx.getChild(dmlTargetIndex + 1);
final SqmRoot<R> root = visitTargetEntity(dmlTargetContext);
if (root.getReferencedPathSource() instanceof SqmPolymorphicRootDescriptor<?>) {
throw new SemanticException(String.format("Target type '%s' in insert statement is not an entity", root.getReferencedPathSource().getHibernateEntityName()));
}
final HqlParser.QueryExpressionContext queryExpressionContext = ctx.queryExpression();
if (queryExpressionContext != null) {
final SqmInsertSelectStatement<R> insertStatement = new SqmInsertSelectStatement<>(root, creationContext.getNodeBuilder());
parameterCollector = insertStatement;
final SqmDmlCreationProcessingState processingState = new SqmDmlCreationProcessingState(insertStatement, this);
processingStateStack.push(processingState);
try {
queryExpressionContext.accept(this);
final SqmCreationProcessingState stateFieldsProcessingState = new SqmCreationProcessingStateImpl(insertStatement, this);
stateFieldsProcessingState.getPathRegistry().register(root);
processingStateStack.push(stateFieldsProcessingState);
try {
for (HqlParser.SimplePathContext stateFieldCtx : targetFieldsSpecContext.simplePath()) {
final SqmPath<?> stateField = (SqmPath<?>) visitSimplePath(stateFieldCtx);
// todo : validate each resolved stateField...
insertStatement.addInsertTargetStateField(stateField);
}
} finally {
processingStateStack.pop();
}
return insertStatement;
} finally {
processingStateStack.pop();
}
} else {
final SqmInsertValuesStatement<R> insertStatement = new SqmInsertValuesStatement<>(root, creationContext.getNodeBuilder());
parameterCollector = insertStatement;
final SqmDmlCreationProcessingState processingState = new SqmDmlCreationProcessingState(insertStatement, this);
processingStateStack.push(processingState);
processingState.getPathRegistry().register(root);
try {
final HqlParser.ValuesListContext valuesListContext = ctx.valuesList();
for (int i = 1; i < valuesListContext.getChildCount(); i += 2) {
final ParseTree values = valuesListContext.getChild(i);
final SqmValues sqmValues = new SqmValues();
for (int j = 1; j < values.getChildCount(); j += 2) {
sqmValues.getExpressions().add((SqmExpression<?>) values.getChild(j).accept(this));
}
insertStatement.getValuesList().add(sqmValues);
}
for (HqlParser.SimplePathContext stateFieldCtx : targetFieldsSpecContext.simplePath()) {
final SqmPath<?> stateField = (SqmPath<?>) visitSimplePath(stateFieldCtx);
// todo : validate each resolved stateField...
insertStatement.addInsertTargetStateField(stateField);
}
return insertStatement;
} finally {
processingStateStack.pop();
}
}
}
Aggregations