use of org.hibernate.hql.internal.ast.tree.FromElementFactory in project hibernate-orm by hibernate.
the class EntityGraphQueryHint method getFromElements.
private List<FromElement> getFromElements(List attributeNodes, FromElement origin, FromClause fromClause, HqlSqlWalker walker, Map<String, FromElement> explicitFetches) {
final List<FromElement> fromElements = new ArrayList<FromElement>();
for (Object obj : attributeNodes) {
final AttributeNode<?> attributeNode = (AttributeNode<?>) obj;
final String attributeName = attributeNode.getAttributeName();
final String className = origin.getClassName();
// TODO: This is ignored by collection types and probably wrong for entity types. Presumably it screws
// with inheritance.
final String role = className + "." + attributeName;
final String classAlias = origin.getClassAlias();
final String originTableAlias = origin.getTableAlias();
final Type propertyType = origin.getPropertyType(attributeName, attributeName);
try {
FromElement fromElement = explicitFetches.get(role);
boolean explicitFromElement = false;
if (fromElement == null) {
if (propertyType.isEntityType()) {
final EntityType entityType = (EntityType) propertyType;
final String[] columns = origin.toColumns(originTableAlias, attributeName, false);
final String tableAlias = walker.getAliasGenerator().createName(entityType.getAssociatedEntityName());
final FromElementFactory fromElementFactory = new FromElementFactory(fromClause, origin, attributeName, classAlias, columns, false);
final JoinSequence joinSequence = walker.getSessionFactoryHelper().createJoinSequence(false, entityType, tableAlias, JoinType.LEFT_OUTER_JOIN, columns);
fromElement = fromElementFactory.createEntityJoin(entityType.getAssociatedEntityName(), tableAlias, joinSequence, true, walker.isInFrom(), entityType, role, null);
} else if (propertyType.isCollectionType()) {
CollectionType collectionType = (CollectionType) propertyType;
final String[] columns = origin.toColumns(originTableAlias, attributeName, false);
final FromElementFactory fromElementFactory = new FromElementFactory(fromClause, origin, attributeName, classAlias, columns, false);
final QueryableCollection queryableCollection = walker.getSessionFactoryHelper().requireQueryableCollection(collectionType.getRole());
fromElement = fromElementFactory.createCollection(queryableCollection, collectionType.getRole(), JoinType.LEFT_OUTER_JOIN, true, false);
}
} else {
explicitFromElement = true;
fromElement.setInProjectionList(true);
fromElement.setFetch(true);
}
if (fromElement != null) {
if (!explicitFromElement) {
fromElements.add(fromElement);
}
// recurse into subgraphs
for (Subgraph<?> subgraph : attributeNode.getSubgraphs().values()) {
fromElements.addAll(getFromElements(subgraph.getAttributeNodes(), fromElement, fromClause, walker, explicitFetches));
}
}
} catch (Exception e) {
throw new QueryException("Could not apply the EntityGraph to the Query!", e);
}
}
return fromElements;
}
use of org.hibernate.hql.internal.ast.tree.FromElementFactory in project hibernate-orm by hibernate.
the class HqlSqlWalker method createFromJoinElement.
@Override
protected void createFromJoinElement(AST path, AST alias, int joinType, AST fetchNode, AST propertyFetch, AST with) throws SemanticException {
boolean fetch = fetchNode != null;
if (fetch && isSubQuery()) {
throw new QueryException("fetch not allowed in subquery from-elements");
}
// the incoming "path" can be either:
// 1) an implicit join path (join p.address.city)
// 2) an entity-join (join com.acme.User)
//
// so make the proper interpretation here...
final EntityPersister entityJoinReferencedPersister = resolveEntityJoinReferencedPersister(path);
if (entityJoinReferencedPersister != null) {
// `path` referenced an entity
final EntityJoinFromElement join = createEntityJoin(entityJoinReferencedPersister, alias, joinType, propertyFetch, with);
((FromReferenceNode) path).setFromElement(join);
} else {
if (path.getType() != SqlTokenTypes.DOT) {
throw new SemanticException("Path expected for join!");
}
DotNode dot = (DotNode) path;
JoinType hibernateJoinType = JoinProcessor.toHibernateJoinType(joinType);
// Tell the dot node about the join type.
dot.setJoinType(hibernateJoinType);
dot.setFetch(fetch);
// Generate an explicit join for the root dot node. The implied joins will be collected and passed up
// to the root dot node.
dot.resolve(true, false, alias == null ? null : alias.getText());
final FromElement fromElement;
if (dot.getDataType() != null && dot.getDataType().isComponentType()) {
if (dot.getDataType().isAnyType()) {
throw new SemanticException("An AnyType attribute cannot be join fetched");
// ^^ because the discriminator (aka, the "meta columns") must be known to the SQL in
// a non-parameterized way.
}
FromElementFactory factory = new FromElementFactory(getCurrentFromClause(), dot.getLhs().getFromElement(), dot.getPropertyPath(), alias == null ? null : alias.getText(), null, false);
fromElement = factory.createComponentJoin((CompositeType) dot.getDataType());
} else {
fromElement = dot.getImpliedJoin();
fromElement.setAllPropertyFetch(propertyFetch != null);
if (with != null) {
if (fetch) {
throw new SemanticException("with-clause not allowed on fetched associations; use filters");
}
handleWithFragment(fromElement, with);
}
}
if (LOG.isDebugEnabled()) {
LOG.debug("createFromJoinElement() : " + getASTPrinter().showAsString(fromElement, "-- join tree --"));
}
}
}
Aggregations