📄 fromelementfactory.java
字号:
if ( implied && inFrom ) { joinSequence.setUseThetaStyle( false ); elem.setUseFromFragment( true ); elem.setImpliedInFromClause( true ); } if ( elem.getWalker().isSubQuery() ) { // two conditions where we need to transform this to a theta-join syntax: // 1) 'elem' is the "root from-element" in correlated subqueries // 2) The DotNode.useThetaStyleImplicitJoins has been set to true // and 'elem' represents an implicit join if ( elem.getFromClause() != elem.getOrigin().getFromClause() ||// ( implied && DotNode.useThetaStyleImplicitJoins ) ) { DotNode.useThetaStyleImplicitJoins ) { // the "root from-element" in correlated subqueries do need this piece elem.setType( FROM_FRAGMENT ); joinSequence.setUseThetaStyle( true ); elem.setUseFromFragment( false ); } } return elem; } FromElement createElementJoin(QueryableCollection queryableCollection) throws SemanticException { FromElement elem; implied = true; //TODO: always true for now, but not if we later decide to support elements() in the from clause inElementsFunction = true; Type elementType = queryableCollection.getElementType(); if ( !elementType.isEntityType() ) { throw new IllegalArgumentException( "Cannot create element join for a collection of non-entities!" ); } this.queryableCollection = queryableCollection; SessionFactoryHelper sfh = fromClause.getSessionFactoryHelper(); FromElement destination = null; String tableAlias = null; EntityPersister entityPersister = queryableCollection.getElementPersister(); tableAlias = fromClause.getAliasGenerator().createName( entityPersister.getEntityName() ); String associatedEntityName = entityPersister.getEntityName(); EntityPersister targetEntityPersister = sfh.requireClassPersister( associatedEntityName ); // Create the FROM element for the target (the elements of the collection). destination = createAndAddFromElement( associatedEntityName, classAlias, targetEntityPersister, ( EntityType ) queryableCollection.getElementType(), tableAlias ); // If the join is implied, then don't include sub-classes on the element. if ( implied ) { destination.setIncludeSubclasses( false ); } fromClause.addCollectionJoinFromElementByPath( path, destination );// origin.addDestination(destination); // Add the query spaces. fromClause.getWalker().addQuerySpaces( entityPersister.getQuerySpaces() ); CollectionType type = queryableCollection.getCollectionType(); String role = type.getRole(); String roleAlias = origin.getTableAlias(); String[] targetColumns = sfh.getCollectionElementColumns( role, roleAlias ); AssociationType elementAssociationType = sfh.getElementAssociationType( type ); // Create the join element under the from element. int joinType = JoinFragment.INNER_JOIN; JoinSequence joinSequence = sfh.createJoinSequence( implied, elementAssociationType, tableAlias, joinType, targetColumns ); elem = initializeJoin( path, destination, joinSequence, targetColumns, origin, false ); elem.setUseFromFragment( true ); // The associated entity is implied, but it must be included in the FROM. elem.setCollectionTableAlias( roleAlias ); // The collection alias is the role. return elem; } private FromElement createCollectionJoin(JoinSequence collectionJoinSequence, String tableAlias) throws SemanticException { String text = queryableCollection.getTableName(); AST ast = createFromElement( text ); FromElement destination = ( FromElement ) ast; Type elementType = queryableCollection.getElementType(); if ( elementType.isCollectionType() ) { throw new SemanticException( "Collections of collections are not supported!" ); } destination.initializeCollection( fromClause, classAlias, tableAlias ); destination.setType( JOIN_FRAGMENT ); // Tag this node as a JOIN. destination.setIncludeSubclasses( false ); // Don't include subclasses in the join. destination.setCollectionJoin( true ); // This is a clollection join. destination.setJoinSequence( collectionJoinSequence ); destination.setOrigin( origin, false ); destination.setCollectionTableAlias(tableAlias);// origin.addDestination( destination );// This was the cause of HHH-242// origin.setType( FROM_FRAGMENT ); // Set the parent node type so that the AST is properly formed. origin.setText( "" ); // The destination node will have all the FROM text. origin.setCollectionJoin( true ); // The parent node is a collection join too (voodoo - see JoinProcessor) fromClause.addCollectionJoinFromElementByPath( path, destination ); fromClause.getWalker().addQuerySpaces( queryableCollection.getCollectionSpaces() ); return destination; } private FromElement createEntityAssociation( String role, String roleAlias, int joinType) throws SemanticException { FromElement elem; Queryable entityPersister = ( Queryable ) queryableCollection.getElementPersister(); String associatedEntityName = entityPersister.getEntityName(); // Get the class name of the associated entity. if ( queryableCollection.isOneToMany() ) { if ( log.isDebugEnabled() ) { log.debug( "createEntityAssociation() : One to many - path = " + path + " role = " + role + " associatedEntityName = " + associatedEntityName ); } JoinSequence joinSequence = createJoinSequence( roleAlias, joinType ); elem = createJoin( associatedEntityName, roleAlias, joinSequence, ( EntityType ) queryableCollection.getElementType(), false ); } else { if ( log.isDebugEnabled() ) { log.debug( "createManyToMany() : path = " + path + " role = " + role + " associatedEntityName = " + associatedEntityName ); } elem = createManyToMany( role, associatedEntityName, roleAlias, entityPersister, ( EntityType ) queryableCollection.getElementType(), joinType ); fromClause.getWalker().addQuerySpaces( queryableCollection.getCollectionSpaces() ); } elem.setCollectionTableAlias( roleAlias ); return elem; } private FromElement createJoin( String entityClass, String tableAlias, JoinSequence joinSequence, EntityType type, boolean manyToMany) throws SemanticException { // origin, path, implied, columns, classAlias, EntityPersister entityPersister = fromClause.getSessionFactoryHelper().requireClassPersister( entityClass ); FromElement destination = createAndAddFromElement( entityClass, classAlias, entityPersister, type, tableAlias ); return initializeJoin( path, destination, joinSequence, getColumns(), origin, manyToMany ); } private FromElement createManyToMany( String role, String associatedEntityName, String roleAlias, Queryable entityPersister, EntityType type, int joinType) throws SemanticException { FromElement elem; SessionFactoryHelper sfh = fromClause.getSessionFactoryHelper(); if ( inElementsFunction /*implied*/ ) { // For implied many-to-many, just add the end join. JoinSequence joinSequence = createJoinSequence( roleAlias, joinType ); elem = createJoin( associatedEntityName, roleAlias, joinSequence, type, true ); } else { // For an explicit many-to-many relationship, add a second join from the intermediate // (many-to-many) table to the destination table. Also, make sure that the from element's // idea of the destination is the destination table. String tableAlias = fromClause.getAliasGenerator().createName( entityPersister.getEntityName() ); String[] secondJoinColumns = sfh.getCollectionElementColumns( role, roleAlias ); // Add the second join, the one that ends in the destination table. JoinSequence joinSequence = createJoinSequence( roleAlias, joinType ); joinSequence.addJoin( sfh.getElementAssociationType( collectionType ), tableAlias, joinType, secondJoinColumns ); elem = createJoin( associatedEntityName, tableAlias, joinSequence, type, false ); elem.setUseFromFragment( true ); } return elem; } private JoinSequence createJoinSequence(String roleAlias, int joinType) { SessionFactoryHelper sessionFactoryHelper = fromClause.getSessionFactoryHelper(); String[] joinColumns = getColumns(); if ( collectionType == null ) { throw new IllegalStateException( "collectionType is null!" ); } return sessionFactoryHelper.createJoinSequence( implied, collectionType, roleAlias, joinType, joinColumns ); } private FromElement createAndAddFromElement( String className, String classAlias, EntityPersister entityPersister, EntityType type, String tableAlias) { if ( !( entityPersister instanceof Joinable ) ) { throw new IllegalArgumentException( "EntityPersister " + entityPersister + " does not implement Joinable!" ); } FromElement element = createFromElement( entityPersister ); initializeAndAddFromElement( element, className, classAlias, entityPersister, type, tableAlias ); return element; } private void initializeAndAddFromElement( FromElement element, String className, String classAlias, EntityPersister entityPersister, EntityType type, String tableAlias) { if ( tableAlias == null ) { AliasGenerator aliasGenerator = fromClause.getAliasGenerator(); tableAlias = aliasGenerator.createName( entityPersister.getEntityName() ); } element.initializeEntity( fromClause, className, entityPersister, type, classAlias, tableAlias ); } private FromElement createFromElement(EntityPersister entityPersister) { Joinable joinable = ( Joinable ) entityPersister; String text = joinable.getTableName(); AST ast = createFromElement( text ); FromElement element = ( FromElement ) ast; return element; } private AST createFromElement(String text) { AST ast = ASTUtil.create( fromClause.getASTFactory(), implied ? IMPLIED_FROM : FROM_FRAGMENT, // This causes the factory to instantiate the desired class. text ); // Reset the node type, because the rest of the system is expecting FROM_FRAGMENT, all we wanted was // for the factory to create the right sub-class. This might get reset again later on anyway to make the // SQL generation simpler. ast.setType( FROM_FRAGMENT ); return ast; } private FromElement initializeJoin( String path, FromElement destination, JoinSequence joinSequence, String[] columns, FromElement origin, boolean manyToMany) { destination.setType( JOIN_FRAGMENT ); destination.setJoinSequence( joinSequence ); destination.setColumns( columns ); destination.setOrigin( origin, manyToMany ); fromClause.addJoinByPathMap( path, destination ); return destination; } private String[] getColumns() { if ( columns == null ) { throw new IllegalStateException( "No foriegn key columns were supplied!" ); } return columns; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -