Given:
- Single table inheritance using discriminator
- One child entity has an OneToMany relationship to a certain entity of type A using FetchMode.SUBSELECT
- Another child entity has another OneToMany relationship to a certain entity of type B also using FetchMode.SUBSELECT
When
- Querying both entities and initializing the first child relationship
Then
- A NPE happens when hibernate wrongly tries to load the 2nd child relationship with entity of type A, which mapping doesn’t exist for the second child type.
@Entity
@Table(name = "MY_ENTITY")
@DiscriminatorColumn(name = "DISC_COL", discriminatorType = DiscriminatorType.INTEGER)
@DiscriminatorValue("0")
public class ParentEntity {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "ID")
Integer id;
}
@Entity
@DiscriminatorValue("1")
public class MyEntityWithAnotherEntities extends ParentEntity {
@OneToMany(mappedBy = "myEntity")
@Fetch(FetchMode.SUBSELECT)
List<AnotherEntity> anotherEntities = new ArrayList<>();
}
@Entity
@DiscriminatorValue("2")
public class MyEntityWithSomeOtherEntities extends ParentEntity {
@OneToMany(mappedBy = "myEntity")
@Fetch(FetchMode.SUBSELECT)
List<SomeOtherEntity> someOtherEntitiesEntities = new ArrayList<>();
}
@Test
public void hhhXXXXTest() throws Exception {
AnotherEntity anotherEntity1 = new AnotherEntity();
MyEntityWithAnotherEntities child1 = new MyEntityWithAnotherEntities();
MyEntityWithSomeOtherEntities child2 = new MyEntityWithSomeOtherEntities();
try (Session s = openSession()) {
Transaction tx = s.beginTransaction();
child1.anotherEntities.add(anotherEntity1);
anotherEntity1.myEntity = child1;
s.persist(child1);
s.persist(child2);
s.persist(anotherEntity1);
tx.commit();
}
try (Session s = openSession()) {
Transaction tx = s.beginTransaction();
Query<ParentEntity> query = s.createQuery("from ParentEntity e order by e.id", ParentEntity.class);
List<ParentEntity> entities = query.list();
assertThat(entities).hasSize(2);
assertThat(entities.get(0)).isInstanceOf(MyEntityWithAnotherEntities.class);
assertThat(((MyEntityWithAnotherEntities) entities.get(0)).anotherEntities).isNotEmpty();
tx.commit();
}
}
The issue happens because SubselectFetch.StandardRegistrationHandler.addKey method wrongly registers a key even for the child entity which doesn’t have that collection mapped. This works fine on latest hibernate 5 series. It doesn’t work in any hibernate 6 series. Failing test scenario to be attached |