Skip to content

Commit 983eec0

Browse files
committed
HHH-18909 fix NPE for READ_ONLY cached entity with array
1 parent 8438e8d commit 983eec0

File tree

2 files changed

+50
-5
lines changed

2 files changed

+50
-5
lines changed

hibernate-core/src/main/java/org/hibernate/sql/results/internal/ResultsHelper.java

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -77,14 +77,18 @@ public static void finalizeCollectionLoading(
7777
}
7878

7979
if ( collectionDescriptor.getCollectionType().hasHolder() ) {
80-
// in case of PersistentArrayHolder we have to realign the EntityEntry loaded state with
81-
// the entity values
80+
// in case of PersistentArrayHolder we have to realign
81+
// the EntityEntry loaded state with the entity values
8282
final Object owner = collectionInstance.getOwner();
8383
final EntityEntry entry = persistenceContext.getEntry( owner );
84-
final PluralAttributeMapping mapping = collectionDescriptor.getAttributeMapping();
85-
final int propertyIndex = mapping.getStateArrayPosition();
8684
final Object[] loadedState = entry.getLoadedState();
87-
loadedState[propertyIndex] = mapping.getValue( owner );
85+
if ( loadedState != null ) {
86+
final PluralAttributeMapping mapping = collectionDescriptor.getAttributeMapping();
87+
final int propertyIndex = mapping.getStateArrayPosition();
88+
loadedState[propertyIndex] = mapping.getValue( owner );
89+
}
90+
// else it must be an immutable entity or loaded in read-only mode,
91+
// but unfortunately we have no way to reliably determine that here
8892
persistenceContext.addCollectionHolder( collectionInstance );
8993
}
9094

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
/*
2+
* SPDX-License-Identifier: Apache-2.0
3+
* Copyright Red Hat Inc. and Hibernate Authors
4+
*/
5+
package org.hibernate.orm.test.cache;
6+
7+
import jakarta.persistence.ElementCollection;
8+
import jakarta.persistence.Entity;
9+
import jakarta.persistence.Id;
10+
import org.hibernate.annotations.Cache;
11+
import org.hibernate.annotations.Immutable;
12+
import org.hibernate.testing.orm.junit.EntityManagerFactoryScope;
13+
import org.hibernate.testing.orm.junit.Jpa;
14+
import org.junit.jupiter.api.Test;
15+
16+
import static org.hibernate.annotations.CacheConcurrencyStrategy.READ_ONLY;
17+
18+
@Jpa(annotatedClasses = CachedReadOnlyArrayTest.Publication.class)
19+
class CachedReadOnlyArrayTest {
20+
21+
@Test
22+
void testReadFromCache(EntityManagerFactoryScope scope) {
23+
scope.inTransaction(em -> {
24+
Publication entity1 = new Publication();
25+
entity1.id = "123l";
26+
em.persist(entity1);
27+
});
28+
scope.inTransaction(em -> em.find(Publication.class, "123l"/*, ReadOnlyMode.READ_ONLY*/));
29+
30+
}
31+
32+
@Immutable
33+
@Entity
34+
@Cache(usage = READ_ONLY)
35+
static class Publication {
36+
@Id
37+
String id;
38+
@ElementCollection
39+
String[] topics;
40+
}
41+
}

0 commit comments

Comments
 (0)