-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 2 posts ] 
Author Message
 Post subject: createAlias() and Criteria API force inner joins
PostPosted: Wed Sep 29, 2004 11:15 pm 
Newbie

Joined: Wed Sep 29, 2004 10:18 pm
Posts: 1
I have run into an issue using the Criteria API that I believe to be
the same as discussed in this thread:

http://forum.hibernate.org/viewtopic.php?t=934119

and this JIRA issue:

http://opensource.atlassian.com/projects/hibernate/browse/HB-1206

I am trying to perform an outer join using Criteria, but as soon
as I introduce an alias via createAlias(), the left outer joins are
forced to inner joins...

Code between sessionFactory.openSession() and session.close():
Code:
  System.out.println(
      "size without aliases: " +
      s.createCriteria(Foo.class)
          .list()
          .size());

  System.out.println(
      "size with aliases: " +
      s.createCriteria(Foo.class)
          .createAlias("bar", "BAR")
          .createAlias("baz", "BAZ")
          .list()
          .size());


The generated SQL (show_sql=true):
Debug level Hibernate log excerpt:
Code:
Hibernate:
  select
    this.id as id2_,
    this.bar_id as bar_id2_,
    this.baz_id as baz_id2_,
    bar1_.id as id0_,
    bar1_.name as name0_,
    baz2_.id as id1_,
    baz2_.name as name1_
  from t_foo this
  left outer join t_bar bar1_ on this.bar_id=bar1_.id
  left outer join t_baz baz2_ on this.baz_id=baz2_.id
  where 1=1

size without aliases: 3

Hibernate:
  select this.id as id2_,
    this.bar_id as bar_id2_,
    this.baz_id as baz_id2_,
    BAR.id as id0_,
    BAR.name as name0_,
    BAZ.id as id1_,
    BAZ.name as name1_
  from t_foo this
  inner join t_bar BAR on this.bar_id=BAR.id
  inner join t_baz BAZ on this.baz_id=BAZ.id
  where 1=1

size with aliases: 0
(some of the foreign keys are null, let me know if the insert statements would be useful)


I've searched the forums and source looking for clues and spent
a few hours with a debugger, but I still can't tell if this behavior
is intentional or if there is a workaround. The forum post and JIRA
comments linked above suggests it might be intentional, but the
replies were fairly brief and didn't give any explanation.

The Criteria API suits the code I am writing better than HQL. Before
I dump my Criteria code and reimplement it in HQL, is there anyone
out there willing to elaborate on why aliases affect the join types?
Is this a feature? Is there a reasonable way to change the behavior
and would a patch that does so be accepted?

Thank you in advance for any replies and, to the developers, thank you
for sharing Hibernate with us.

(Remainder of requested information below signature.)

--Brad


Hibernate version: 2.1.6

Mapping documents:
Code:
<hibernate-mapping>

  <class name="eg.Foo" table="t_foo">
    <id name="id"><generator class="assigned"/></id>
    <!--
    <property name="barId" column="bar_id"/>
    <property name="bazId" column="baz_id"/>
    -->
    <many-to-one name="bar" class="eg.Bar" column="bar_id"/>
    <many-to-one name="baz" class="eg.Baz" column="baz_id"/>
  </class>

  <class name="eg.Bar" table="t_bar">
    <id name="id"><generator class="assigned"/></id>
    <property name="name"/>
  </class>

  <class name="eg.Baz" table="t_baz">
    <id name="id"><generator class="assigned"/></id>
    <property name="name"/>
  </class>

</hibernate-mapping>



Full stack trace of any exception that occurs:
Not applicable.

Name and version of the database you are using:
Oracle 9i


Top
 Profile  
 
 Post subject: Me too
PostPosted: Thu Nov 04, 2004 12:39 pm 
Newbie

Joined: Fri Aug 27, 2004 1:52 pm
Posts: 9
Yes, I've noticed the same thing. I searched the code and found the responsible code. Its a method in CriteriaLoader:


Code:
   protected int getJoinType(
      AssociationType type,
      int config,
      String path,
      String table,
      String[] foreignKeyColumns,
      SessionFactoryImplementor factory)
      throws MappingException {
      
      if ( criteria.isJoin(path) ) {
         return JoinFragment.INNER_JOIN;
      }
      else {
         FetchMode fm = criteria.getFetchMode(path);
         if ( fm==null || fm==FetchMode.DEFAULT ) {
            return super.getJoinType(type, config, path, table, foreignKeyColumns, factory);
         }
         else {
            return (fm==FetchMode.EAGER) ? JoinFragment.LEFT_OUTER_JOIN : -1;
         }
      }
   }


There you can see it explicitly checks to see if the association path is a criteria join and decides to force the inner join. It looks to me like it was pretty intentional. Perhaps they just decided that they didn't want to expose that much complexity in the criteria API, although it seems like it could easily have been an overloaded method on createAlias.

There didn't seem to be any easy way to have this behavior overridden with a subclass as this is pretty deep in the hibernate code.


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 2 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.