-->
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: Criteria ignores not-null attribute - inner join not outer
PostPosted: Thu Mar 17, 2005 2:06 pm 
Newbie

Joined: Tue Oct 05, 2004 11:28 am
Posts: 10
Hibernate version:
3.0 RC1

Mapping documents:
Code:
  <class name="Foo" table="FOO">
    <id name="id" type="integer" unsaved-value="null">
      <column name="FOO_ID" not-null="true" />
      <generator class="assigned" />
    </id>
   
    <property name="fooName">
      <column name="FOO_NAME" not-null="false" />
    </property>

    <many-to-one name="bar" class="Bar" not-null="false" >
      <column name="BAR_ID" not-null="false" />
    </many-to-one>
  </class>

  <class name="Bar" table="BAR">
    <id name="id" type="integer" unsaved-value="null">
      <column name="BAR_ID" not-null="true" />
      <generator class="assigned" />
    </id>
     
    <property name="barName">
      <column name="BAR_NAME" not-null="false" />
    </property>
  </class>


Code:
public class Foo
{
    private Integer _id;
    private String _fooName;
    private Bar _bar;
    public Foo() {}
    public Integer getId() { return _id; }
    public void setId(Integer integer) { _id = integer;  }
    public String getFooName() { return _fooName; }
    public void setFooName(String string) { _fooName = string; }
    public Bar getBar() { return _bar; }
    public void setBar(Bar bar) { _bar = bar; }
}

public class Bar
{
    private Integer _id;
    private String _barName;
    public Bar() {}
    public Integer getId() { return _id; }
    public void setId(Integer integer) { _id = integer; }
    public String getBarName() { return _barName; }
    public void setBarName(String string) { _barName = string; }
}


Code between sessionFactory.openSession() and session.close():
Code:
Criteria c = session.createCriteria(Foo.class);
c.createCriteria("bar", "b");
c.add(Restrictions.or(Restrictions.eq("fooName", "bob"), Restrictions.eq("b.barName", "joe")));
c.list();

Name and version of the database you are using:
MySQL 4.1x

The generated SQL (show_sql=true):
Code:
select this_.FOO_ID as FOO1_1_, this_.FOO_NAME as FOO2_52_1_,
this_.BAR_ID as BAR3_52_1_, b1_.BAR_ID as BAR1_0_, b1_.BAR_NAME as BAR2_53_0_
from FOO this_
inner join BAR b1_ on this_.BAR_ID=b1_.BAR_ID
where (this_.FOO_NAME=? or b1_.BAR_NAME=?)



Each row in the FOO table has a reference to a row in the BAR table which may or may not be null. I want to write a Criteria that will return all Foo objects named 'bob' OR all foo objects associated with Bar objects named 'joe'. If the not-null attribute on the many-to-one is honored, then the join to the BAR table should be a left join, not an inner join. The inner join results in the query NOT returning Foos named bob if they have a null BAR reference.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Mar 21, 2005 4:39 pm 
Newbie

Joined: Tue Oct 05, 2004 11:28 am
Posts: 10
Ok, I read this one:

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

I changed line 146 in CriteriaLoader.java from

Code:
    if ( translator.isJoin(path) ) {
       return JoinFragment.INNER_JOIN;
    }


to

Code:
    if ( translator.isJoin(path) ) {
       return JoinFragment.LEFT_OUTER_JOIN;
    }


and now I get the expected rows back from Criteria queries. This is probably a really bad idea, but I don't see how Criteria can work effectively if it uses inner joins when I have nullable many-to-ones.

I originally changed the code to return LEFT_OUTER_JOIN if the association was nullable, but this was not enough; I actually have a nullable many-to-one where the associated entity is a joined-subclass and an inner join in the joined subclass also prevented my root entity rows from being selected by the Criteria query.

P.S. Long live the Criteria API! I don't see the value in writing HQL over SQL if I still have to mess around with string concatenations to do dynamic queries.


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.