Hibernate does not use left outer joins on one-to-one when using a named query.

Solution Verified - Updated -

Issue

I have got the following entities:

@Entity
@NamedQueries({@NamedQuery(name="byId", query="select f from FooEntity f where f.id = :id")})

public class FooEntity {
  @Id
  @GeneratedValue

private Long id;

    @OneToOne(cascade=CascadeType.ALL)
    @PrimaryKeyJoinColumn
    BarEntity bar;


    String foo;
    ...

    @Entity
    public class BarEntity {
    @Id
    @GeneratedValue
    private Long id;

    String bar;
    ...

But when I load the Foo entity through find or through a named query, I get different queries generated:


public void testFooBar() throws Exception { FooEntity foo = new FooEntity(); foo.setFoo("foo"); BarEntity bar = new BarEntity(); bar.setBar("bar"); foo.setBar(bar); log.info("---------- saving foo entity"); delegate.saveObject(foo); Long id = foo.getId(); assertEquals(id, bar.getId()); log.info("---------- loading foo entity through find"); foo = delegate.loadById1(id); assertEquals("foo", foo.getFoo()); assertEquals("bar", foo.getBar().getBar()); log.info("---------- loading foo entity through named query"); foo = delegate.loadById2(id); assertEquals("foo", foo.getFoo()); assertEquals("bar", foo.getBar().getBar()); } public void saveObject(Object obj) { getEntityManager().persist(obj); } public FooEntity loadById1(long id) { return getEntityManager().find(FooEntity.class, id); } public FooEntity loadById2(long id) { return (FooEntity) getEntityManager().createNamedQuery("byId").setParameter("id", id).getSingleResult(); }

this test passes, with the following log:

INFO  com.xxxx.transaction2.dao.negoce.TrNegoceDAOTest - ---------- saving foo entity
DEBUG org.hibernate.SQL - insert into FooEntity (id, foo) values (null, ?)
DEBUG org.hibernate.SQL - call identity()
DEBUG org.hibernate.SQL - insert into BarEntity (id, bar) values (null, ?)
DEBUG org.hibernate.SQL - call identity()
INFO  com.xxxx.transaction2.dao.negoce.TrNegoceDAOTest - ---------- loading foo entity through find
DEBUG org.hibernate.SQL - select fooentity0_.id as id0_1_, fooentity0_.foo as foo0_1_, barentity1_.id as id1_0_, barentity1_.bar as bar1_0_ from FooEntity fooentity0_ left outer join BarEntity barentity1_ on fooentity0_.id=barentity1_.id where fooentity0_.id=?
INFO  com.xxxx.transaction2.dao.negoce.TrNegoceDAOTest - ---------- loading foo entity through named query
DEBUG org.hibernate.SQL - select top ? fooentity0_.id as id0_, fooentity0_.foo as foo0_ from FooEntity fooentity0_ where fooentity0_.id=?
DEBUG org.hibernate.SQL - select barentity0_.id as id1_0_, barentity0_.bar as bar1_0_ from BarEntity barentity0_ where barentity0_.id=?

When the find() is used, only one query with a left outer join is generated. However, if I do something similar with a named query, then I get 2 queries. This makes it very inefficient.

What is causing this behaviour? Can we influence the queries being generated when using the named query?

If I change the named query in:

select f from FooEntity f left join f.bar where f.id = :id

Then I still get 2 queries:

DEBUG org.hibernate.SQL - select top ? fooentity0_.id as id0_, fooentity0_.foo as foo0_ from FooEntity fooentity0_ left outer join BarEntity barentity1_ on fooentity0_.id=barentity1_.id where fooentity0_.id=?
DEBUG org.hibernate.SQL - select barentity0_.id as id1_0_, barentity0_.bar as bar1_0_ from BarEntity barentity0_ where barentity0_.id=?

With the first one doing the left outer join, but the second one is generated nonetheless.

Environment

JBoss Enterprise Application Platform 5.1.0

Subscriber exclusive content

A Red Hat subscription provides unlimited access to our knowledgebase, tools, and much more.

Current Customers and Partners

Log in for full access

Log In

New to Red Hat?

Learn more about Red Hat subscriptions

Using a Red Hat product through a public cloud?

How to access this content