I tried to create a minimal entity mapping to reproduce this issue. Changing any FetchMode configuration in the mapping would "avoid" the issue. Also disabling batch fetch would "avoid" the issue. This is the minimal mapping scenario that I was able to create from my real case:
@Entity
@Table(name = "ENTITY_A")
public class EntityA {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "ID")
Integer id;
@JoinColumn(name = "ENTITY_B")
@ManyToOne
EntityB entityB;
}
@Entity
@Table(name = "ENTITY_B")
public class EntityB {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "ID")
Integer id;
@OneToMany(mappedBy = "entityB")
@Fetch(FetchMode.SUBSELECT)
List<EntityC> listOfEntitiesC = new ArrayList<>();
@JoinColumn(name = "ENTITY_D")
@ManyToOne
EntityD entityD;
}
@Entity
@Table(name = "ENTITY_C")
public class EntityC {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "ID")
Integer id;
@JoinColumn(name = "ENTITY_B")
@ManyToOne
EntityB entityB;
}
@Entity
@Table(name = "ENTITY_D")
public class EntityD {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "ID")
Integer id;
@JoinColumn(name = "ENTITY_E")
@ManyToOne
@Fetch(FetchMode.SELECT)
EntityE entityE;
@JoinColumn(name = "OPENING_B")
@ManyToOne
EntityB openingB;
@JoinColumn(name = "CLOSING_B")
@ManyToOne
EntityB closingB;
@OneToMany(mappedBy = "entityD")
List<EntityB> listOfEntitiesB = new ArrayList<>();
}
@Entity
@Table(name = "ENTITY_E")
public class EntityE {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "ID")
Integer id;
@JoinColumn(name = "ENTITY_D")
@ManyToOne
EntityD entityD;
}
@Override
protected void configure(Configuration configuration) {
super.configure(configuration);
configuration.setProperty(AvailableSettings.SHOW_SQL, Boolean.TRUE.toString());
configuration.setProperty(AvailableSettings.FORMAT_SQL, Boolean.TRUE.toString());
configuration.setProperty(AvailableSettings.DEFAULT_BATCH_FETCH_SIZE, "10");
}
@Test
public void hhhXXXXTest() throws Exception {
try (Session s = openSession()) {
Transaction tx = s.beginTransaction();
EntityA entityA = new EntityA();
EntityB entityB = new EntityB();
EntityC entityC = new EntityC();
EntityD entityD = new EntityD();
EntityE entityE = new EntityE();
entityA.entityB = entityB;
entityB.entityD = entityD;
entityB.listOfEntitiesC.add(entityC);
entityC.entityB = entityB;
entityD.entityE = entityE;
entityD.listOfEntitiesB.add(entityB);
entityD.openingB = entityB;
entityE.entityD = entityD;
s.persist(entityA);
s.persist(entityB);
s.persist(entityC);
s.persist(entityD);
s.persist(entityE);
tx.commit();
}
try (Session s = openSession()) {
List<EntityE> entitiesE = s.createQuery("select e from EntityE e", EntityE.class).getResultList();
assertThat(entitiesE).hasSize(1);
List<EntityA> entitiesA = s.createQuery("select a from EntityA a", EntityA.class).getResultList();
assertThat(entitiesA).hasSize(1);
assertThat(entitiesA.get(0).entityB.listOfEntitiesC).hasSize(1);
}
}
The generated query to load EntityE.listOfEntitiesC is wrong since c1_0.ID is the wrong path to be used
Hibernate:
select
l1_0.ENTITY_B,
l1_0.ID
from
ENTITY_C l1_0
where
l1_0.ENTITY_B in(select
c1_0.ID
from
ENTITY_D e1_0
left join
ENTITY_B c1_0
on c1_0.ID=e1_0.CLOSING_B
left join
ENTITY_D e2_0
on e2_0.ID=c1_0.ENTITY_D
left join
ENTITY_B o1_0
on o1_0.ID=e2_0.OPENING_B
left join
ENTITY_B o2_0
on o2_0.ID=e1_0.OPENING_B
left join
ENTITY_D e6_0
on e6_0.ID=o2_0.ENTITY_D
left join
ENTITY_B c3_0
on c3_0.ID=e6_0.CLOSING_B
where
array_contains(?,e1_0.ID))
A failing test scenario is to be attached |