Jones (
https://hibernate.atlassian.net/secure/ViewProfile.jspa?accountId=557058%...
) *created* an issue
Hibernate ORM (
https://hibernate.atlassian.net/browse/HHH?atlOrigin=eyJpIjoiNDM5OWYzOGNh...
) / Bug (
https://hibernate.atlassian.net/browse/HHH-16569?atlOrigin=eyJpIjoiNDM5OW...
) HHH-16569 (
https://hibernate.atlassian.net/browse/HHH-16569?atlOrigin=eyJpIjoiNDM5OW...
) Batch fetch leads to some collections to be wrongly initialized with empty due to wrong
generated SQL (
https://hibernate.atlassian.net/browse/HHH-16569?atlOrigin=eyJpIjoiNDM5OW...
)
Issue Type: Bug Affects Versions: 6.2.2 Assignee: Unassigned Created: 08/May/2023 02:53 AM
Priority: Critical Reporter: Jones (
https://hibernate.atlassian.net/secure/ViewProfile.jspa?accountId=557058%...
)
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);
}
}
java.lang.AssertionError:
Expected size:<1> but was:<0> in:
<[]>
at org.hibernate.bugs.ORMUnitTestCase.hhhXXXXTest(ORMUnitTestCase.java:97)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at
java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
at
java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:568)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:59)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:56)
at
org.hibernate.testing.junit4.ExtendedFrameworkMethod.invokeExplosively(ExtendedFrameworkMethod.java:45)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27)
at
org.junit.internal.runners.statements.FailOnTimeout$CallableStatement.call(FailOnTimeout.java:299)
at
org.junit.internal.runners.statements.FailOnTimeout$CallableStatement.call(FailOnTimeout.java:293)
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
at java.base/java.lang.Thread.run(Thread.java:833)
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
(
https://hibernate.atlassian.net/browse/HHH-16569#add-comment?atlOrigin=ey...
) Add Comment (
https://hibernate.atlassian.net/browse/HHH-16569#add-comment?atlOrigin=ey...
)
Get Jira notifications on your phone! Download the Jira Cloud app for Android (
https://play.google.com/store/apps/details?id=com.atlassian.android.jira....
) or iOS (
https://itunes.apple.com/app/apple-store/id1006972087?pt=696495&ct=Em...
) This message was sent by Atlassian Jira (v1001.0.0-SNAPSHOT#100225- sha1:5ff5564 )