First of all, I would like to thanks everybody that contributes to this forum and hibernate, the best ORM solution (in my opnion at least :-)).
I´m migrating a huge project from OpenJPA to Hibernate. So far we could get everything to work, but there´s one thing that we still couldn´t find the answer. We have a very large entity graph, so we use a lot of oneToMany relationships. The problem is that when I try to load a Entity it doesn´t respect the 'hibernate.max_fetch_depth' param, it just loads every single EAGER relationship regardless of the depth.
I´ve tried to do the query using JPQL and also with the CriteriaBuilder, the results is always the same it loads every EAGER realtion.
I´ve downloaded hibernate sources and I´m debugging trying to understand the code, it seens that Hibernate analyses the 'max_fetch_depth' while loading the classes (just when the application is deploy), when the maximum level is reached it starts creating the joins with JoinType.NONE. But later on when it´s actually executing the query, it seems to ignore this.
I´ve created a simple project with five entities (entity1 has oneToMany entity2 and so on), I´m always able to reproduce this behavior.
Is this the expected behavior? I´m using JBoss AS7 with hibernate 4.0.1.
The classes used for testing are:
Code:
@Entity
public class Entity1{
@Id
private Long id1;
@OneToMany(mappedBy = "entity1", cascade = CascadeType.ALL, fetch = FetchType.EAGER)
private List<Entity2 > entity2 = new ArrayList<Entity2 >();
}
@Entity
public class Entity2 {
@Id
private Long id2;
private static final long serialVersionUID = 1L;
@ManyToOne
@JoinColumn(name="id1")
private Entity1 entity1;
@OneToMany(mappedBy = "entity2", cascade = CascadeType.ALL, fetch = FetchType.EAGER)
private List<Entity3> entity3 = new ArrayList<Entity3>();
}
and so on until Entity5.
The test is done with hibernate.max_fetch_depth=2, but the result is five selects. Here follows the test source and the log.
Code:
Entity1 entity1 = new Entity1();
Entity2 entity2 = new Entity2();
Entity3 entity3 = new Entity3();
Entity4 entity4 = new Entity4();
Entity5 entity5 = new Entity5();
entity1.getEntitys2().add(entity2);
entity2.setEntity1(entity1);
entity2.getEntitys3().add(entity3);
entity3.setEntity2(entity2);
entity3.getEntitys4().add(entity4);
entity4.setEntity3(entity3);
entity4.getEntitys5().add(entity5);
entity5.setEntity4(entity4);
em.persist(entidade1);
em.createQuery("SELECT e FROM " + Entity1.getName() + " e ").getResultList();
This results in selecting 5 leves, not only two as specified by hibernate.max_fetch_depth=2. The hibernate log is:
Code:
16:47:05,223 INFO [stdout] (pool-4-thread-1) Hibernate: insert into Entity1 (id1) values (?)
16:47:05,510 INFO [stdout] (pool-4-thread-1) Hibernate: insert into Entity2 (id1, id2) values (?, ?)
16:47:05,582 INFO [stdout] (pool-4-thread-1) Hibernate: insert into Entity3 (id2, id3) values (?, ?)
16:47:05,669 INFO [stdout] (pool-4-thread-1) Hibernate: insert into Entity4 (id3, id4) values (?, ?)
16:47:05,764 INFO [stdout] (pool-4-thread-1) Hibernate: insert into Entity5 (id4, id5) values (?, ?)
16:47:05,936 INFO [stdout] (pool-4-thread-1) Hibernate: select entity1x0_.id1 as id1_0_ from Entity1 entity1x0_
16:47:05,947 INFO [stdout] (pool-4-thread-1) Hibernate: select entitys2x0_.id1 as id2_0_1_, entitys2x0_.id2 as id1_1_, entitys2x0_.id2 as id1_4_0_, entitys2x0_.id1 as id2_4_0_ from Entity2 entitys2x0_ where entitys2x0_.id1=?
16:47:05,955 INFO [stdout] (pool-4-thread-1) Hibernate: select entitys3x0_.id2 as id2_4_1_, entitys3x0_.id3 as id1_1_, entitys3x0_.id3 as id1_2_0_, entitys3x0_.id2 as id2_2_0_ from Entity3 entitys3x0_ where entitys3x0_.id2=?
16:47:05,960 INFO [stdout] (pool-4-thread-1) Hibernate: select entitys4x0_.id3 as id2_2_1_, entitys4x0_.id4 as id1_1_, entitys4x0_.id4 as id1_1_0_, entitys4x0_.id3 as id2_1_0_ from Entity4 entitys4x0_ where entitys4x0_.id3=?
16:47:05,965 INFO [stdout] (pool-4-thread-1) Hibernate: select entitys5x0_.id4 as id2_1_1_, entitys5x0_.id5 as id1_1_, entitys5x0_.id5 as id1_5_0_, entitys5x0_.id4 as id2_5_0_ from Entity5 entitys5x0_ where entitys5x0_.id4=?
Thanks in advance,
Aristides