Skip to content

Commit d90704e

Browse files
peter1123581321mbellade
authored andcommitted
HHH-18876 ArrayIndexOutOfBoundsException in ArrayInitializer with ListIndexBase
1 parent 1eff544 commit d90704e

File tree

3 files changed

+122
-2
lines changed

3 files changed

+122
-2
lines changed

hibernate-core/src/main/java/org/hibernate/sql/results/graph/collection/internal/ArrayInitializer.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -130,10 +130,13 @@ protected void resolveInstanceSubInitializers(ImmediateCollectionInitializerData
130130
final Initializer<?> initializer = elementAssembler.getInitializer();
131131
if ( initializer != null ) {
132132
final RowProcessingState rowProcessingState = data.getRowProcessingState();
133-
final Integer index = listIndexAssembler.assemble( rowProcessingState );
133+
Integer index = listIndexAssembler.assemble( rowProcessingState );
134134
if ( index != null ) {
135135
final PersistentArrayHolder<?> arrayHolder = getCollectionInstance( data );
136136
assert arrayHolder != null;
137+
if ( indexBase != 0 ) {
138+
index -= indexBase;
139+
}
137140
initializer.resolveInstance( Array.get( arrayHolder.getArray(), index ), rowProcessingState );
138141
}
139142
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
/*
2+
* SPDX-License-Identifier: Apache-2.0
3+
* Copyright Red Hat Inc. and Hibernate Authors
4+
*/
5+
package org.hibernate.orm.test.mapping.collections;
6+
7+
import jakarta.persistence.CascadeType;
8+
import jakarta.persistence.Entity;
9+
import jakarta.persistence.FetchType;
10+
import jakarta.persistence.Id;
11+
import jakarta.persistence.JoinColumn;
12+
import jakarta.persistence.JoinTable;
13+
import jakarta.persistence.ManyToMany;
14+
import jakarta.persistence.ManyToOne;
15+
import jakarta.persistence.OneToMany;
16+
import jakarta.persistence.OrderColumn;
17+
import org.hibernate.annotations.ListIndexBase;
18+
import org.hibernate.testing.orm.junit.DomainModel;
19+
import org.hibernate.testing.orm.junit.JiraKey;
20+
import org.hibernate.testing.orm.junit.SessionFactory;
21+
import org.hibernate.testing.orm.junit.SessionFactoryScope;
22+
import org.junit.jupiter.api.Test;
23+
24+
25+
import static org.junit.jupiter.api.Assertions.assertEquals;
26+
import static org.junit.jupiter.api.Assertions.assertNotNull;
27+
28+
@JiraKey("HHH-18876")
29+
@DomainModel(
30+
annotatedClasses = {
31+
OrderColumnListIndexArrayInitializerTest.Person.class,
32+
OrderColumnListIndexArrayInitializerTest.Phone.class,
33+
}
34+
)
35+
@SessionFactory
36+
class OrderColumnListIndexArrayInitializerTest {
37+
38+
@Test
39+
void hhh18876Test(SessionFactoryScope scope) {
40+
41+
// prepare data
42+
scope.inTransaction( session -> {
43+
44+
// person
45+
Person person = new Person();
46+
person.id = 1L;
47+
session.persist( person );
48+
49+
// add phone
50+
Phone phone = new Phone();
51+
phone.id = 1L;
52+
phone.person = person;
53+
54+
person.phones = new Phone[1];
55+
person.phones[0] = phone;
56+
57+
// add children
58+
Person children = new Person();
59+
children.id = 2L;
60+
children.mother = person;
61+
62+
person.children = new Person[1];
63+
person.children[0] = children;
64+
} );
65+
66+
// load and assert
67+
scope.inTransaction( session -> {
68+
Person person = session.createSelectionQuery( "select p from Person p where id=1", Person.class )
69+
.getSingleResult();
70+
assertNotNull( person );
71+
assertEquals( 1, person.phones.length );
72+
assertNotNull( person.phones[0] );
73+
assertEquals( 1, person.children.length );
74+
assertEquals( person, person.children[0].mother );
75+
} );
76+
}
77+
78+
@Entity(name = "Person")
79+
public static class Person {
80+
81+
@Id
82+
Long id;
83+
84+
@OneToMany(fetch = FetchType.EAGER, mappedBy = "person", cascade = CascadeType.ALL)
85+
@OrderColumn(name = "order_id")
86+
@ListIndexBase(100)
87+
Phone[] phones;
88+
89+
@ManyToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
90+
@JoinTable(name = "parent_child_relationships", joinColumns = @JoinColumn(name = "parent_id"),
91+
inverseJoinColumns = @JoinColumn(name = "child_id"))
92+
@OrderColumn(name = "pos")
93+
@ListIndexBase(200)
94+
Person[] children;
95+
96+
@ManyToOne
97+
@JoinColumn(name = "mother_id")
98+
Person mother;
99+
}
100+
101+
@Entity(name = "Phone")
102+
public static class Phone {
103+
104+
@Id
105+
Long id;
106+
107+
@ManyToOne
108+
Person person;
109+
}
110+
}

hibernate-core/src/test/java/org/hibernate/orm/test/mapping/collections/OrderColumnListIndexHHH18771ListInitializerTest.java

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@
2626
import jakarta.persistence.OrderColumn;
2727

2828
import static org.hibernate.testing.transaction.TransactionUtil.doInJPA;
29+
import static org.junit.jupiter.api.Assertions.assertEquals;
30+
import static org.junit.jupiter.api.Assertions.assertNotNull;
2931

3032
/**
3133
* @author Selaron
@@ -50,7 +52,12 @@ public void testLifecycle() {
5052
person.getChildren().get( 0 ).setMother( person );
5153
} );
5254
doInJPA( this::entityManagerFactory, entityManager -> {
53-
entityManager.find( Person.class, 1L );
55+
Person person = entityManager.find( Person.class, 1L );
56+
assertNotNull( person );
57+
assertEquals( 1, person.getPhones().size() );
58+
assertNotNull( person.getPhones().get( 0 ) );
59+
assertEquals( 1, person.getChildren().size() );
60+
assertEquals( person, person.getChildren().get( 0 ).getMother() );
5461
} );
5562
}
5663

0 commit comments

Comments
 (0)