alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

Hibernate example source code file (DotNode.java)

This example Hibernate source code file (DotNode.java) is included in the DevDaily.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Java - Hibernate tags/keywords

ast, dotnode, fromelement, fromelement, fromreferencenode, fromreferencenode, override, queryexception, semanticexception, semanticexception, sqlnode, string, string, type

The Hibernate DotNode.java source code

/*
 * Hibernate, Relational Persistence for Idiomatic Java
 *
 * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
 * indicated by the @author tags or express copyright attribution
 * statements applied by the authors.  All third-party contributions are
 * distributed under license by Red Hat Middleware LLC.
 *
 * This copyrighted material is made available to anyone wishing to use, modify,
 * copy, or redistribute it subject to the terms and conditions of the GNU
 * Lesser General Public License, as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
 * for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this distribution; if not, write to:
 * Free Software Foundation, Inc.
 * 51 Franklin Street, Fifth Floor
 * Boston, MA  02110-1301  USA
 *
 */
package org.hibernate.hql.internal.ast.tree;

import org.hibernate.engine.internal.JoinSequence;
import org.hibernate.internal.CoreMessageLogger;
import org.hibernate.QueryException;
import org.hibernate.hql.internal.CollectionProperties;
import org.hibernate.hql.internal.antlr.SqlTokenTypes;
import org.hibernate.hql.internal.ast.util.ASTUtil;
import org.hibernate.hql.internal.ast.util.ColumnHelper;
import org.hibernate.internal.util.StringHelper;
import org.hibernate.persister.collection.QueryableCollection;
import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.sql.JoinFragment;
import org.hibernate.sql.JoinType;
import org.hibernate.type.CollectionType;
import org.hibernate.type.EntityType;
import org.hibernate.type.Type;
import org.jboss.logging.Logger;
import antlr.SemanticException;
import antlr.collections.AST;

/**
 * Represents a reference to a property or alias expression.  This should duplicate the relevant behaviors in
 * PathExpressionParser.
 *
 * @author Joshua Davis
 */
public class DotNode extends FromReferenceNode implements DisplayableNode, SelectExpression {

	///////////////////////////////////////////////////////////////////////////
	// USED ONLY FOR REGRESSION TESTING!!!!
	//
	// todo : obviously get rid of all this junk ;)
	///////////////////////////////////////////////////////////////////////////
	public static boolean useThetaStyleImplicitJoins = false;
	public static boolean REGRESSION_STYLE_JOIN_SUPPRESSION = false;
	public static interface IllegalCollectionDereferenceExceptionBuilder {
		public QueryException buildIllegalCollectionDereferenceException(String collectionPropertyName, FromReferenceNode lhs);
	}
	public static final IllegalCollectionDereferenceExceptionBuilder DEF_ILLEGAL_COLL_DEREF_EXCP_BUILDER = new IllegalCollectionDereferenceExceptionBuilder() {
		public QueryException buildIllegalCollectionDereferenceException(String propertyName, FromReferenceNode lhs) {
			String lhsPath = ASTUtil.getPathText( lhs );
			return new QueryException( "illegal attempt to dereference collection [" + lhsPath + "] with element property reference [" + propertyName + "]" );
		}
	};
	public static IllegalCollectionDereferenceExceptionBuilder ILLEGAL_COLL_DEREF_EXCP_BUILDER = DEF_ILLEGAL_COLL_DEREF_EXCP_BUILDER;
	///////////////////////////////////////////////////////////////////////////

    private static final CoreMessageLogger LOG = Logger.getMessageLogger(CoreMessageLogger.class, DotNode.class.getName());

	private static final int DEREF_UNKNOWN = 0;
	private static final int DEREF_ENTITY = 1;
	private static final int DEREF_COMPONENT = 2;
	private static final int DEREF_COLLECTION = 3;
	private static final int DEREF_PRIMITIVE = 4;
	private static final int DEREF_IDENTIFIER = 5;
	private static final int DEREF_JAVA_CONSTANT = 6;

	/**
	 * The identifier that is the name of the property.
	 */
	private String propertyName;
	/**
	 * The full path, to the root alias of this dot node.
	 */
	private String path;
	/**
	 * The unresolved property path relative to this dot node.
	 */
	private String propertyPath;

	/**
	 * The column names that this resolves to.
	 */
	private String[] columns;

	/**
	 * The type of join to create.   Default is an inner join.
	 */
	private JoinType joinType = JoinType.INNER_JOIN;

	/**
	 * Fetch join or not.
	 */
	private boolean fetch = false;

	/**
	 * The type of dereference that hapened (DEREF_xxx).
	 */
	private int dereferenceType = DEREF_UNKNOWN;

	private FromElement impliedJoin;

	/**
	 * Sets the join type for this '.' node structure.
	 *
	 * @param joinType The type of join to use.
	 * @see JoinFragment
	 */
	public void setJoinType(JoinType joinType) {
		this.joinType = joinType;
	}

	private String[] getColumns() throws QueryException {
		if ( columns == null ) {
			// Use the table fromElement and the property name to get the array of column names.
			String tableAlias = getLhs().getFromElement().getTableAlias();
			columns = getFromElement().toColumns( tableAlias, propertyPath, false );
		}
		return columns;
	}

	@Override
    public String getDisplayText() {
		StringBuilder buf = new StringBuilder();
		FromElement fromElement = getFromElement();
		buf.append( "{propertyName=" ).append( propertyName );
		buf.append( ",dereferenceType=" ).append( getWalker().getASTPrinter().getTokenTypeName( dereferenceType ) );
		buf.append( ",propertyPath=" ).append( propertyPath );
		buf.append( ",path=" ).append( getPath() );
		if ( fromElement != null ) {
			buf.append( ",tableAlias=" ).append( fromElement.getTableAlias() );
			buf.append( ",className=" ).append( fromElement.getClassName() );
			buf.append( ",classAlias=" ).append( fromElement.getClassAlias() );
		}
		else {
			buf.append( ",no from element" );
		}
		buf.append( '}' );
		return buf.toString();
	}

	/**
	 * Resolves the left hand side of the DOT.
	 *
	 * @throws SemanticException
	 */
	@Override
    public void resolveFirstChild() throws SemanticException {
		FromReferenceNode lhs = ( FromReferenceNode ) getFirstChild();
		SqlNode property = ( SqlNode ) lhs.getNextSibling();

		// Set the attributes of the property reference expression.
		String propName = property.getText();
		propertyName = propName;
		// If the uresolved property path isn't set yet, just use the property name.
		if ( propertyPath == null ) {
			propertyPath = propName;
		}
		// Resolve the LHS fully, generate implicit joins.  Pass in the property name so that the resolver can
		// discover foreign key (id) properties.
		lhs.resolve( true, true, null, this );
		setFromElement( lhs.getFromElement() );			// The 'from element' that the property is in.

		checkSubclassOrSuperclassPropertyReference( lhs, propName );
	}

	@Override
    public void resolveInFunctionCall(boolean generateJoin, boolean implicitJoin) throws SemanticException {
		if ( isResolved() ) {
			return;
		}
		Type propertyType = prepareLhs();			// Prepare the left hand side and get the data type.
		if ( propertyType!=null && propertyType.isCollectionType() ) {
			resolveIndex(null);
		}
		else {
			resolveFirstChild();
			super.resolve(generateJoin, implicitJoin);
		}
	}


	public void resolveIndex(AST parent) throws SemanticException {
		if ( isResolved() ) {
			return;
		}
		Type propertyType = prepareLhs();			// Prepare the left hand side and get the data type.
		dereferenceCollection( ( CollectionType ) propertyType, true, true, null, parent );
	}

	public void resolve(boolean generateJoin, boolean implicitJoin, String classAlias, AST parent)
	throws SemanticException {
		// If this dot has already been resolved, stop now.
		if ( isResolved() ) {
			return;
		}
		Type propertyType = prepareLhs(); // Prepare the left hand side and get the data type.

		// If there is no data type for this node, and we're at the end of the path (top most dot node), then
		// this might be a Java constant.
		if ( propertyType == null ) {
			if ( parent == null ) {
				getWalker().getLiteralProcessor().lookupConstant( this );
			}
			// If the propertyType is null and there isn't a parent, just
			// stop now... there was a problem resolving the node anyway.
			return;
		}

		if ( propertyType.isComponentType() ) {
			// The property is a component...
			checkLhsIsNotCollection();
			dereferenceComponent( parent );
			initText();
		}
		else if ( propertyType.isEntityType() ) {
			// The property is another class..
			checkLhsIsNotCollection();
			dereferenceEntity( ( EntityType ) propertyType, implicitJoin, classAlias, generateJoin, parent );
			initText();
		}
		else if ( propertyType.isCollectionType() ) {
			// The property is a collection...
			checkLhsIsNotCollection();
			dereferenceCollection( ( CollectionType ) propertyType, implicitJoin, false, classAlias, parent );
		}
		else {
			// Otherwise, this is a primitive type.
			if ( ! CollectionProperties.isAnyCollectionProperty( propertyName ) ) {
				checkLhsIsNotCollection();
			}
			dereferenceType = DEREF_PRIMITIVE;
			initText();
		}
		setResolved();
	}

	private void initText() {
		String[] cols = getColumns();
		String text = StringHelper.join( ", ", cols );
		if ( cols.length > 1 && getWalker().isComparativeExpressionClause() ) {
			text = "(" + text + ")";
		}
		setText( text );
	}

	private Type prepareLhs() throws SemanticException {
		FromReferenceNode lhs = getLhs();
		lhs.prepareForDot( propertyName );
		return getDataType();
	}

	private void dereferenceCollection(CollectionType collectionType, boolean implicitJoin, boolean indexed, String classAlias, AST parent)
	throws SemanticException {

		dereferenceType = DEREF_COLLECTION;
		String role = collectionType.getRole();

		//foo.bars.size (also handles deprecated stuff like foo.bars.maxelement for backwardness)
		boolean isSizeProperty = getNextSibling()!=null &&
			CollectionProperties.isAnyCollectionProperty( getNextSibling().getText() );

		if ( isSizeProperty ) indexed = true; //yuck!

		QueryableCollection queryableCollection = getSessionFactoryHelper().requireQueryableCollection( role );
		String propName = getPath();
		FromClause currentFromClause = getWalker().getCurrentFromClause();

		if ( getWalker().getStatementType() != SqlTokenTypes.SELECT && indexed && classAlias == null ) {
			// should indicate that we are processing an INSERT/UPDATE/DELETE
			// query with a subquery implied via a collection property
			// function. Here, we need to use the table name itself as the
			// qualification alias.
			// TODO : verify this works for all databases...
			// TODO : is this also the case in non-"indexed" scenarios?
			String alias = getLhs().getFromElement().getQueryable().getTableName();
			columns = getFromElement().toColumns( alias, propertyPath, false, true );
		}

		//We do not look for an existing join on the same path, because
		//it makes sense to join twice on the same collection role
		FromElementFactory factory = new FromElementFactory(
		        currentFromClause,
		        getLhs().getFromElement(),
		        propName,
				classAlias,
		        getColumns(),
		        implicitJoin
		);
		FromElement elem = factory.createCollection( queryableCollection, role, joinType, fetch, indexed );

        LOG.debugf("dereferenceCollection() : Created new FROM element for %s : %s", propName, elem);

		setImpliedJoin( elem );
		setFromElement( elem );	// This 'dot' expression now refers to the resulting from element.

		if ( isSizeProperty ) {
			elem.setText("");
			elem.setUseWhereFragment(false);
		}

		if ( !implicitJoin ) {
			EntityPersister entityPersister = elem.getEntityPersister();
			if ( entityPersister != null ) {
				getWalker().addQuerySpaces( entityPersister.getQuerySpaces() );
			}
		}
		getWalker().addQuerySpaces( queryableCollection.getCollectionSpaces() );	// Always add the collection's query spaces.
	}

	private void dereferenceEntity(EntityType entityType, boolean implicitJoin, String classAlias, boolean generateJoin, AST parent) throws SemanticException {
		checkForCorrelatedSubquery( "dereferenceEntity" );
		// three general cases we check here as to whether to render a physical SQL join:
		// 1) is our parent a DotNode as well?  If so, our property reference is
		// 		being further de-referenced...
		// 2) is this a DML statement
		// 3) we were asked to generate any needed joins (generateJoins==true) *OR*
		//		we are currently processing a select or from clause
		// (an additional check is the REGRESSION_STYLE_JOIN_SUPPRESSION check solely intended for the test suite)
		//
		// The REGRESSION_STYLE_JOIN_SUPPRESSION is an additional check
		// intended solely for use within the test suite.  This forces the
		// implicit join resolution to behave more like the classic parser.
		// The underlying issue is that classic translator is simply wrong
		// about its decisions on whether or not to render an implicit join
		// into a physical SQL join in a lot of cases.  The piece it generally
		// tends to miss is that INNER joins effect the results by further
		// restricting the data set!  A particular manifestation of this is
		// the fact that the classic translator will skip the physical join
		// for ToOne implicit joins *if the query is shallow*; the result
		// being that Query.list() and Query.iterate() could return
		// different number of results!
		DotNode parentAsDotNode = null;
		String property = propertyName;
		final boolean joinIsNeeded;

		if ( isDotNode( parent ) ) {
			// our parent is another dot node, meaning we are being further dereferenced.
			// thus we need to generate a join unless the parent refers to the associated
			// entity's PK (because 'our' table would know the FK).
			parentAsDotNode = ( DotNode ) parent;
			property = parentAsDotNode.propertyName;
			joinIsNeeded = generateJoin && !isReferenceToPrimaryKey( parentAsDotNode.propertyName, entityType );
		}
		else if ( ! getWalker().isSelectStatement() ) {
			// in non-select queries, the only time we should need to join is if we are in a subquery from clause
			joinIsNeeded = getWalker().getCurrentStatementType() == SqlTokenTypes.SELECT && getWalker().isInFrom();
		}
		else if ( REGRESSION_STYLE_JOIN_SUPPRESSION ) {
			// this is the regression style determination which matches the logic of the classic translator
			joinIsNeeded = generateJoin && ( !getWalker().isInSelect() || !getWalker().isShallowQuery() );
		}
		else {
			joinIsNeeded = generateJoin || ( getWalker().isInSelect() || getWalker().isInFrom() );
		}

		if ( joinIsNeeded ) {
			dereferenceEntityJoin( classAlias, entityType, implicitJoin, parent );
		}
		else {
			dereferenceEntityIdentifier( property, parentAsDotNode );
		}

	}

	private boolean isDotNode(AST n) {
		return n != null && n.getType() == SqlTokenTypes.DOT;
	}

	private void dereferenceEntityJoin(String classAlias, EntityType propertyType, boolean impliedJoin, AST parent)
	throws SemanticException {
		dereferenceType = DEREF_ENTITY;
        if (LOG.isDebugEnabled()) LOG.debugf("dereferenceEntityJoin() : generating join for %s in %s (%s) parent = %s",
                                             propertyName,
                                             getFromElement().getClassName(),
                                             classAlias == null ? "<no alias>" : classAlias,
                                             ASTUtil.getDebugString(parent));
		// Create a new FROM node for the referenced class.
		String associatedEntityName = propertyType.getAssociatedEntityName();
		String tableAlias = getAliasGenerator().createName( associatedEntityName );

		String[] joinColumns = getColumns();
		String joinPath = getPath();

		if ( impliedJoin && getWalker().isInFrom() ) {
			joinType = getWalker().getImpliedJoinType();
		}

		FromClause currentFromClause = getWalker().getCurrentFromClause();
		FromElement elem = currentFromClause.findJoinByPath( joinPath );

///////////////////////////////////////////////////////////////////////////////
//
// This is the piece which recognizes the condition where an implicit join path
// resolved earlier in a correlated subquery is now being referenced in the
// outer query.  For 3.0final, we just let this generate a second join (which
// is exactly how the old parser handles this).  Eventually we need to add this
// logic back in and complete the logic in FromClause.promoteJoin; however,
// FromClause.promoteJoin has its own difficulties (see the comments in
// FromClause.promoteJoin).
//
//		if ( elem == null ) {
//			// see if this joinPath has been used in a "child" FromClause, and if so
//			// promote that element to the outer query
//			FromClause currentNodeOwner = getFromElement().getFromClause();
//			FromClause currentJoinOwner = currentNodeOwner.locateChildFromClauseWithJoinByPath( joinPath );
//			if ( currentJoinOwner != null && currentNodeOwner != currentJoinOwner ) {
//				elem = currentJoinOwner.findJoinByPathLocal( joinPath );
//				if ( elem != null ) {
//					currentFromClause.promoteJoin( elem );
//					// EARLY EXIT!!!
//					return;
//				}
//			}
//		}
//
///////////////////////////////////////////////////////////////////////////////

		boolean found = elem != null;
		// even though we might find a pre-existing element by join path, for FromElements originating in a from-clause
		// we should only ever use the found element if the aliases match (null != null here).  Implied joins are
		// always (?) ok to reuse.
		boolean useFoundFromElement = found && ( elem.isImplied() || areSame( classAlias, elem.getClassAlias() ) );

		if ( ! useFoundFromElement ) {
			// If this is an implied join in a from element, then use the impled join type which is part of the
			// tree parser's state (set by the gramamar actions).
			JoinSequence joinSequence = getSessionFactoryHelper()
				.createJoinSequence( impliedJoin, propertyType, tableAlias, joinType, joinColumns );

			// If the lhs of the join is a "component join", we need to go back to the
			// first non-component-join as the origin to properly link aliases and
			// join columns
			FromElement lhsFromElement = getLhs().getFromElement();
			while ( lhsFromElement != null &&  ComponentJoin.class.isInstance( lhsFromElement ) ) {
				lhsFromElement = lhsFromElement.getOrigin();
			}
			if ( lhsFromElement == null ) {
				throw new QueryException( "Unable to locate appropriate lhs" );
			}

			FromElementFactory factory = new FromElementFactory(
			        currentFromClause,
					lhsFromElement,
					joinPath,
					classAlias,
					joinColumns,
					impliedJoin
			);
			elem = factory.createEntityJoin(
					associatedEntityName,
					tableAlias,
					joinSequence,
					fetch,
					getWalker().isInFrom(),
					propertyType
			);
		}
		else {
			// NOTE : addDuplicateAlias() already performs nullness checks on the alias.
			currentFromClause.addDuplicateAlias( classAlias, elem );
		}
		setImpliedJoin( elem );
		getWalker().addQuerySpaces( elem.getEntityPersister().getQuerySpaces() );
		setFromElement( elem );	// This 'dot' expression now refers to the resulting from element.
	}

	private boolean areSame(String alias1, String alias2) {
		// again, null != null here
		return !StringHelper.isEmpty( alias1 ) && !StringHelper.isEmpty( alias2 ) && alias1.equals( alias2 );
	}

	private void setImpliedJoin(FromElement elem) {
		this.impliedJoin = elem;
		if ( getFirstChild().getType() == SqlTokenTypes.DOT ) {
			DotNode dotLhs = ( DotNode ) getFirstChild();
			if ( dotLhs.getImpliedJoin() != null ) {
				this.impliedJoin = dotLhs.getImpliedJoin();
			}
		}
	}

	@Override
    public FromElement getImpliedJoin() {
		return impliedJoin;
	}

	/**
	 * Is the given property name a reference to the primary key of the associated
	 * entity construed by the given entity type?
	 * <p/>
	 * For example, consider a fragment like order.customer.id
	 * (where order is a from-element alias).  Here, we'd have:
	 * propertyName = "id" AND
	 * owningType = ManyToOneType(Customer)
	 * and are being asked to determine whether "customer.id" is a reference
	 * to customer's PK...
	 *
	 * @param propertyName The name of the property to check.
	 * @param owningType The type represeting the entity "owning" the property
	 * @return True if propertyName references the entity's (owningType->associatedEntity)
	 * primary key; false otherwise.
	 */
	private boolean isReferenceToPrimaryKey(String propertyName, EntityType owningType) {
		EntityPersister persister = getSessionFactoryHelper()
				.getFactory()
				.getEntityPersister( owningType.getAssociatedEntityName() );
		if ( persister.getEntityMetamodel().hasNonIdentifierPropertyNamedId() ) {
			// only the identifier property field name can be a reference to the associated entity's PK...
			return propertyName.equals( persister.getIdentifierPropertyName() ) && owningType.isReferenceToPrimaryKey();
		}
        // here, we have two possibilities:
        // 1) the property-name matches the explicitly identifier property name
        // 2) the property-name matches the implicit 'id' property name
        // the referenced node text is the special 'id'
        if (EntityPersister.ENTITY_ID.equals(propertyName)) return owningType.isReferenceToPrimaryKey();
        String keyPropertyName = getSessionFactoryHelper().getIdentifierOrUniqueKeyPropertyName(owningType);
        return keyPropertyName != null && keyPropertyName.equals(propertyName) && owningType.isReferenceToPrimaryKey();
	}

	private void checkForCorrelatedSubquery(String methodName) {
        if (isCorrelatedSubselect()) LOG.debugf("%s() : correlated subquery", methodName);
	}

	private boolean isCorrelatedSubselect() {
		return getWalker().isSubQuery() &&
			getFromElement().getFromClause() != getWalker().getCurrentFromClause();
	}

	private void checkLhsIsNotCollection() throws SemanticException {
		if ( getLhs().getDataType() != null && getLhs().getDataType().isCollectionType() ) {
			throw ILLEGAL_COLL_DEREF_EXCP_BUILDER.buildIllegalCollectionDereferenceException( propertyName, getLhs() );
		}
	}
	private void dereferenceComponent(AST parent) {
		dereferenceType = DEREF_COMPONENT;
		setPropertyNameAndPath( parent );
	}

	private void dereferenceEntityIdentifier(String propertyName, DotNode dotParent) {
		// special shortcut for id properties, skip the join!
		// this must only occur at the _end_ of a path expression
        LOG.debugf("dereferenceShortcut() : property %s in %s does not require a join.",
                   propertyName,
                   getFromElement().getClassName());

		initText();
		setPropertyNameAndPath( dotParent ); // Set the unresolved path in this node and the parent.
		// Set the text for the parent.
		if ( dotParent != null ) {
			dotParent.dereferenceType = DEREF_IDENTIFIER;
			dotParent.setText( getText() );
			dotParent.columns = getColumns();
		}
	}

	private void setPropertyNameAndPath(AST parent) {
		if ( isDotNode( parent ) ) {
			DotNode dotNode = ( DotNode ) parent;
			AST lhs = dotNode.getFirstChild();
			AST rhs = lhs.getNextSibling();
			propertyName = rhs.getText();
			propertyPath = propertyPath + "." + propertyName; // Append the new property name onto the unresolved path.
			dotNode.propertyPath = propertyPath;
            LOG.debugf("Unresolved property path is now '%s'", dotNode.propertyPath);
        } else LOG.debugf("Terminal propertyPath = [%s]", propertyPath);
	}

	@Override
    public Type getDataType() {
		if ( super.getDataType() == null ) {
			FromElement fromElement = getLhs().getFromElement();
            if (fromElement == null) return null;
			// If the lhs is a collection, use CollectionPropertyMapping
			Type propertyType = fromElement.getPropertyType( propertyName, propertyPath );
            LOG.debugf("getDataType() : %s -> %s", propertyPath, propertyType);
			super.setDataType( propertyType );
		}
		return super.getDataType();
	}

	public void setPropertyPath(String propertyPath) {
		this.propertyPath = propertyPath;
	}

	public String getPropertyPath() {
		return propertyPath;
	}

	public FromReferenceNode getLhs() {
		FromReferenceNode lhs = ( ( FromReferenceNode ) getFirstChild() );
		if ( lhs == null ) {
			throw new IllegalStateException( "DOT node with no left-hand-side!" );
		}
		return lhs;
	}

	/**
	 * Returns the full path of the node.
	 *
	 * @return the full path of the node.
	 */
	@Override
    public String getPath() {
		if ( path == null ) {
			FromReferenceNode lhs = getLhs();
			if ( lhs == null ) {
				path = getText();
			}
			else {
				SqlNode rhs = ( SqlNode ) lhs.getNextSibling();
				path = lhs.getPath() + "." + rhs.getOriginalText();
			}
		}
		return path;
	}

	public void setFetch(boolean fetch) {
		this.fetch = fetch;
	}

	public void setScalarColumnText(int i) throws SemanticException {
		String[] sqlColumns = getColumns();
		ColumnHelper.generateScalarColumns( this, sqlColumns, i );
	}

	/**
	 * Special method to resolve expressions in the SELECT list.
	 *
	 * @throws SemanticException if this cannot be resolved.
	 */
	public void resolveSelectExpression() throws SemanticException {
		if ( getWalker().isShallowQuery() || getWalker().getCurrentFromClause().isSubQuery() ) {
			resolve(false, true);
		}
		else {
			resolve(true, false);
			Type type = getDataType();
			if ( type.isEntityType() ) {
				FromElement fromElement = getFromElement();
				fromElement.setIncludeSubclasses( true ); // Tell the destination fromElement to 'includeSubclasses'.
				if ( useThetaStyleImplicitJoins ) {
					fromElement.getJoinSequence().setUseThetaStyle( true );	// Use theta style (for regression)
					// Move the node up, after the origin node.
					FromElement origin = fromElement.getOrigin();
					if ( origin != null ) {
						ASTUtil.makeSiblingOfParent( origin, fromElement );
					}
				}
			}
		}

		FromReferenceNode lhs = getLhs();
		while ( lhs != null ) {
			checkSubclassOrSuperclassPropertyReference( lhs, lhs.getNextSibling().getText() );
			lhs = ( FromReferenceNode ) lhs.getFirstChild();
		}
	}

	public void setResolvedConstant(String text) {
		path = text;
		dereferenceType = DEREF_JAVA_CONSTANT;
		setResolved(); // Don't resolve the node again.
	}

	private boolean checkSubclassOrSuperclassPropertyReference(FromReferenceNode lhs, String propertyName) {
		if ( lhs != null && !( lhs instanceof IndexNode ) ) {
			final FromElement source = lhs.getFromElement();
			if ( source != null ) {
				source.handlePropertyBeingDereferenced( lhs.getDataType(), propertyName );
			}
		}
		return false;
	}
}

Other Hibernate examples (source code examples)

Here is a short list of links related to this Hibernate DotNode.java source code file:

... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.