@@ -702,12 +702,10 @@ void CreateFromJoinElement(
702702 // 2) an entity-join (join com.acme.User)
703703 //
704704 // so make the proper interpretation here...
705- var entityJoinReferencedPersister = ResolveEntityJoinReferencedPersister ( path ) ;
706- if ( entityJoinReferencedPersister != null )
705+ // DOT node processing was moved to prefer implicit join path before probing for entity join
706+ if ( path . Type == IDENT )
707707 {
708- var entityJoin = CreateEntityJoin ( entityJoinReferencedPersister , alias , joinType , with ) ;
709- ( ( FromReferenceNode ) path ) . FromElement = entityJoin ;
710- SetPropertyFetch ( entityJoin , propertyFetch , alias ) ;
708+ ProcessAsEntityJoin ( ) ;
711709 return ;
712710 }
713711 // The path AST should be a DotNode, and it should have been evaluated already.
@@ -725,6 +723,7 @@ void CreateFromJoinElement(
725723
726724 // Generate an explicit join for the root dot node. The implied joins will be collected and passed up
727725 // to the root dot node.
726+ dot . SkipSemiResolve = true ;
728727 dot . Resolve ( true , false , alias == null ? null : alias . Text ) ;
729728
730729 FromElement fromElement ;
@@ -738,7 +737,8 @@ void CreateFromJoinElement(
738737 fromElement = dot . GetImpliedJoin ( ) ;
739738 if ( fromElement == null )
740739 {
741- throw new InvalidPathException ( "Invalid join: " + dot . Path ) ;
740+ ProcessAsEntityJoin ( ) ;
741+ return ;
742742 }
743743 SetPropertyFetch ( fromElement , propertyFetch , alias ) ;
744744
@@ -762,6 +762,15 @@ void CreateFromJoinElement(
762762 {
763763 log . Debug ( "createFromJoinElement() : {0}" , _printer . ShowAsString ( fromElement , "-- join tree --" ) ) ;
764764 }
765+
766+ void ProcessAsEntityJoin ( )
767+ {
768+ var node = ( FromReferenceNode ) path ;
769+ var entityJoinReferencedPersister = ResolveEntityJoinReferencedPersister ( node ) ;
770+ var entityJoin = CreateEntityJoin ( entityJoinReferencedPersister , alias , joinType , with ) ;
771+ node . FromElement = entityJoin ;
772+ SetPropertyFetch ( entityJoin , propertyFetch , alias ) ;
773+ }
765774 }
766775
767776 private EntityJoinFromElement CreateEntityJoin (
@@ -790,42 +799,29 @@ private EntityJoinFromElement CreateEntityJoin(
790799 return join ;
791800 }
792801
793- private IQueryable ResolveEntityJoinReferencedPersister ( IASTNode path )
802+ private IQueryable ResolveEntityJoinReferencedPersister ( FromReferenceNode path )
794803 {
795- string entityName = GetEntityJoinCandidateEntityName ( path ) ;
804+ string entityName = path . Path ;
796805
797806 var persister = SessionFactoryHelper . FindQueryableUsingImports ( entityName ) ;
798807 if ( persister == null && entityName != null )
799808 {
800809 var implementors = SessionFactoryHelper . Factory . GetImplementors ( entityName ) ;
801810 //Possible case - join on interface
802811 if ( implementors . Length == 1 )
803- persister = SessionFactoryHelper . FindQueryableUsingImports ( implementors [ 0 ] ) ;
812+ persister = ( IQueryable ) SessionFactoryHelper . Factory . TryGetEntityPersister ( implementors [ 0 ] ) ;
804813 }
805814
806815 if ( persister != null )
807816 return persister ;
808817
809818 if ( path . Type == IDENT )
810819 {
811- // Since IDENT node is not expected for implicit join path, we can throw on not found persister
812820 throw new QuerySyntaxException ( entityName + " is not mapped" ) ;
813821 }
814822
815- return null ;
816- }
817-
818- private static string GetEntityJoinCandidateEntityName ( IASTNode path )
819- {
820- switch ( path . Type )
821- {
822- case IDENT :
823- return ( ( IdentNode ) path ) . Path ;
824- case DOT :
825- return ASTUtil . GetPathText ( path ) ;
826- }
827-
828- return null ;
823+ //Keep old exception for DOT node
824+ throw new InvalidPathException ( "Invalid join: " + entityName ) ;
829825 }
830826
831827 private static string GetPropertyPath ( DotNode dotNode , IASTNode alias )
0 commit comments