Hi,
I am having trouble using a criteria query to retrieve objects with a one-to-one relationship to other objects with a restriction that the other side of the relationship is not set.
As a simple example, I have EntityA which has an ID and a name, and EntityB which has an ID and a name. There is a bidirectional one-to-one mapping between the entities, mapped by the entityA property of EntityB.
I have created an Eclipse project that includes source for EntityA and EntityB, and uses the Hibernate 3.2 (GA) Core and Annotations libraries and the MySQL Connector (3.1.13) to demonstrate the above. It can be downloaded from
http://home.zip-it.org/~wrose/hibcq.zip.
I have done the configuration using Hibernate annotations. The generated schema looks like (MySQL dialect):
Code:
create table EntityA (
id integer not null auto_increment,
name varchar(64) not null,
primary key (id)
) type=InnoDB;
create table EntityB (
id integer not null auto_increment,
name varchar(64) not null,
entityA_id integer,
primary key (id)
) type=InnoDB;
alter table EntityB
add index FK457309F4DADA97B (entityA_id),
add constraint FK457309F4DADA97B foreign key (entityA_id) references EntityA (id);
If I run a Criteria query looking for instances of EntityB where the associated EntityA is not set, I get a sensible SQL query:
Java:Code:
List l = s.createCriteria(EntityB.class).add(Restrictions.isNull("entityA")).list();
SQL:Code:
select this_.id as id1_1_,
this_.name as name1_1_,
this_.entityA_id as entityA3_1_1_,
entitya2_.id as id0_0_,
entitya2_.name as name0_0_
from EntityB this_ left outer join EntityA entitya2_ on this_.entityA_id=entitya2_.id
where this_.entityA_id is null
But, if I try to run a similar Criteria query from the other end of the association, the where clause is not what I would expect:
Java:Code:
List l = s.createCriteria(EntityA.class).add(Restrictions.isNull("entityB")).list();
SQL:Code:
select this_.id as id0_1_,
this_.name as name0_1_,
entityb2_.id as id1_0_,
entityb2_.name as name1_0_,
entityb2_.entityA_id as entityA3_1_0_
from EntityA this_ left outer join EntityB entityb2_ on this_.id=entityb2_.entityA_id
where this_.id is null
I think this should end with 'where entityb2_.id is null'. I tried using the .createCriteria() method that allows you to specify restrictions on an association, e.g.:
Code:
List l = s.createCriteria(EntityA.class).createCriteria("entityB").add(Restrictions.isNull("id")).list();
This leads to the left join becoming an inner join, however, which means the linked id can never be null.
Does anybody know if the behaviour I am seeing is a bug or the intended effect?