Orlando Pirlog (
https://hibernate.atlassian.net/secure/ViewProfile.jspa?accountId=5d5277e...
) *created* an issue
Hibernate ORM (
https://hibernate.atlassian.net/browse/HHH?atlOrigin=eyJpIjoiNDRmMTRjZWZk...
) / Bug (
https://hibernate.atlassian.net/browse/HHH-16405?atlOrigin=eyJpIjoiNDRmMT...
) HHH-16405 (
https://hibernate.atlassian.net/browse/HHH-16405?atlOrigin=eyJpIjoiNDRmMT...
) Eager fields are not fetched when using ScrollableResults (
https://hibernate.atlassian.net/browse/HHH-16405?atlOrigin=eyJpIjoiNDRmMT...
)
Issue Type: Bug Affects Versions: 5.3.11, 5.6.15 Assignee: Unassigned Components:
hibernate-core Created: 30/Mar/2023 07:31 AM Priority: Major Reporter: Orlando Pirlog (
https://hibernate.atlassian.net/secure/ViewProfile.jspa?accountId=5d5277e...
)
Let’s consider that we have two entities: Course and Student, where Student has many
Course(s), a one-to-many relation like in the below example:
@Entity
@Table(name = "courses")
public class Course implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "course_id", unique = true, nullable = false)
protected Integer id;
...
}
@Entity
@Table(name = "students")
public class Student {
@Id
@Column(unique = true, nullable = false)
private Integer studentId;
@OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
private List<Course> courses = new ArrayList<>();
...
}
Please note that the courses field in Student is eagerly fetched.
Starting from these entities we’ve generated some entries in the database:
sudentRepo.save(createStudentWithCourses(1, 1, 2));
sudentRepo.save(createStudentWithCourses(2, 3, 4));
Later, we want to retrieve these entities and we have two options:
Option #1 - Everything works as expected we have students with courses.
@Test
public void test_whenUsingList_WorksAsExpected_WithAnyHibernate5_3_11_plus() throws
HibernateException {
//obtain session factory
SessionFactory sessionFactory = factory.unwrap(SessionFactory.class);
//open session
Session session = sessionFactory.openSession();
//Obtain students via list()
List<Student> studentList = session
.createQuery("from org.example.Student")
.list();
//close session
session.close();
//expecting to have at least 1 student at index 0
Student student = studentList.get(0);
//expecting to have a course with id 1
Assert.assertEquals(1, student.getCourses().get(0).getId().intValue());
}
Option #2 - Doesn’t work as expected starting with version 5.3.11.Final. We have students…
but no courses linked to them.
@Test
public void
test_whenUsingScroll_FailsWithLazyInitializationException_StartingWithHibernate5_3_11()
throws HibernateException {
//obtain session factory
SessionFactory sessionFactory = factory.unwrap(SessionFactory.class);
//open session
Session session = sessionFactory.openSession();
//Obtain students via ScrollableResults
ScrollableResults scroll = session
.createQuery("from org.example.Student")
.scroll(ScrollMode.FORWARD_ONLY);
ScrollableResultsIterator<Student> iterator = new
ScrollableResultsIterator(scroll);
Spliterator spliterator = Spliterators.spliteratorUnknownSize(iterator, 256);
Stream<Student> stream = StreamSupport.stream(spliterator, false);
List<Student> studentList = stream.collect(Collectors.toList());
//close session
session.close();
//expecting to have at least 1 student at index 0
Student student = studentList.get(0);
//expecting to have a course with id 1
Assert.assertEquals(1, student.getCourses().get(0).getId().intValue());
//But what happens is that the following exception is thrown
//org.hibernate.LazyInitializationException: failed to lazily initialize a collection
of role: org.example.Student.courses, could not initialize proxy - no Session
}
When we need to use the second option, due to performance reasons, we are not able to
obtain entities with their EAGER fields fetched and we think this behaviour should be
corrected.
Note: (We hope we will not influence your judgment related to this task…)
Debugging inside hibernate code, we’ve found that once with the changes related to
https://hibernate.atlassian.net/browse/HHH-11147 the following line was added in
org.hibernate.internal. ScrollableResultsImpl # prepareCurrentRow :
private void prepareCurrentRow(boolean underlyingScrollSuccessful) {
...
persistenceContext.beforeLoad();
...
}
which further resulted in having a StatefulPersistenceContext # loadCounter equal with 1,
and when StatefulPersistenceContext # initializeNonLazyCollections is invoked nothing is
executed due to the first check if ( loadCounter == 0 ) {...
Attached a set of two tests (in AppTest) highlighting the problem.
(
https://hibernate.atlassian.net/browse/HHH-16405#add-comment?atlOrigin=ey...
) Add Comment (
https://hibernate.atlassian.net/browse/HHH-16405#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#100219- sha1:6a6077b )