0

So here is my problem:

I have 2 classes Person and department.

Person :

@Entity
public class Personne
{
    @Id
    private Long id;

    private String name;

    @ManyToOne(fetch=FetchType.EAGER)
    @JoinColumn(name="dept_id")
    @Fetch(FetchMode.JOIN)
    private Departement dept;


    // getter & setter
}

Department :

@Entity
public class Departement
{
    @Id
    private Long id;

    private String name;

    // getter & setter

}

I want to select only departement of a personn with a criteria query so i use Projection:

My Code :

Criteria crt = session.createCriteria(Personne.class);
            crt.createAlias("dept", "d",JoinType.LEFT_OUTER_JOIN);
            crt.setProjection(Projections.projectionList().add(Projections.property("dept")));
            crt.add(Restrictions.eq("id", 1L));

Above query works well but i get 2 queries whereas i expect only 1 since my fetch type is eager.

Log :

[use] 2017-08-16 16:23:07,113 DEBUG [main] SqlStatementLogger.logStatement(109) | select this_.dept_id as y0_ from Personne this_ left outer join Departement d1_ on this_.dept_id=d1_.id where this_.id=?
[use] 2017-08-16 16:23:07,119 DEBUG [main] SqlStatementLogger.logStatement(109) | select departemen0_.id as id1_0_0_, departemen0_.name as name2_0_0_ from Departement departemen0_ where departemen0_.id=?

it seems that projection of entity fires n+1 select. Does that make sense?

can anyone help me with this?

Thanks

Neil Stockton
  • 11,383
  • 3
  • 34
  • 29
Abass A
  • 713
  • 6
  • 14
  • I think you must doing a sysout or doing something else after criteria execution that is forcing hibernate to fire the second query. Can you show the full code after session.createCriteria(...) method? – Madhusudana Reddy Sunnapu Aug 16 '17 at 14:32
  • @MadhusudanaReddySunnapu, thks for your reply, no i just do `crt.list();` after this code nothing more. – Abass A Aug 16 '17 at 14:40
  • What happens if you remove the `@JoinColumn` and `@Fetch` annotations on the mapping? – Naros Aug 16 '17 at 14:46
  • @Naros , the same thing, 2 queries fired. – Abass A Aug 16 '17 at 15:09
  • If i had to guess, its because the association is `optional=true`. I bet you'd get a single query if you specified the many-to-one as `optional=false` and don't allow a null relation. – Naros Aug 17 '17 at 15:29
  • @Naros, no still the same with `optional=false`. thanks – Abass A Aug 17 '17 at 16:07

1 Answers1

0

EAGER does not mean that less queries will be performed, only that the queries will be performed when the owner entity is queried.

What you can use is the @FetchMode annotation, in your case I would assume you would want a FetchMode.JOIN.

FechtMode javadoc: https://docs.jboss.org/hibernate/orm/5.2/javadocs/org/hibernate/FetchMode.html

Either way, be careful with the results, please check the gabrielgiussi answer from FetchMode Join vs SubSelect as he goes into detail how the fetch modes work.

Mário Fernandes
  • 1,822
  • 1
  • 21
  • 21
  • Thank you for you reply, but i already use @FetchMode annotation with FetchMode.JOIN and i was expecting it fetch departement with an outer join at time a personn is fetched but it does'nt. – Abass A Aug 17 '17 at 09:14
  • But if you already have the fetch type and everything, you do not need to do the crt.setProjection(Projections.projectionList().add(Projections.property("dept")));, it will already be brought with the query – Mário Fernandes Aug 17 '17 at 09:17
  • Yes that's true but if i don't use projection criteria query retrieve all fields of all tables in the query and this can lead to performance issue in some case, so i just want to select the one i need but it seems that using projection disable hibernate fecthing strategy. – Abass A Aug 17 '17 at 09:26
  • That's actually not a problem then, why don't you add the dept_id as a normal column? Something like @Column(name = "dept_id", nullable = false, updatable = false) private Integer departmentId;? That way you don't even need the join – Mário Fernandes Aug 17 '17 at 09:29
  • Yes i could work like this or find others ways but my question was especially about why hibernate fires 2 queries instead of one despite the fetch strategy . Thanks for your help – Abass A Aug 17 '17 at 09:39
  • That's fair, no problem, I guess I didn't help that much at all :) – Mário Fernandes Aug 17 '17 at 09:42