Skip to content

Commit c6bf358

Browse files
committed
HHH-19276 - Add test for issue
Signed-off-by: Jan Schatteman <[email protected]>
1 parent 9a6d421 commit c6bf358

File tree

2 files changed

+91
-0
lines changed

2 files changed

+91
-0
lines changed

hibernate-core/src/main/java/org/hibernate/type/BasicTypeRegistry.java

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,18 @@ public BasicTypeRegistry(TypeConfiguration typeConfiguration){
5656
this.typeConfiguration = typeConfiguration;
5757
}
5858

59+
/**
60+
* @apiNote For strictly internal (testing) use ONLY. It can be removed without any prior warning.
61+
*/
62+
@Internal
63+
protected BasicTypeRegistry(BasicTypeRegistry basicTypeRegistry){
64+
this.typeConfiguration = basicTypeRegistry.typeConfiguration;
65+
this.registryValues.putAll( basicTypeRegistry.registryValues );
66+
this.primed = basicTypeRegistry.primed;
67+
this.typesByName.putAll( basicTypeRegistry.typesByName );
68+
this.typeReferencesByName.putAll( basicTypeRegistry.typeReferencesByName );
69+
}
70+
5971
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
6072
// Access
6173

@@ -67,6 +79,14 @@ private JdbcTypeRegistry getJdbcTypeRegistry() {
6779
return typeConfiguration.getJdbcTypeRegistry();
6880
}
6981

82+
/**
83+
* @apiNote This method is for strictly internal (testing) use ONLY. It can be removed without any prior warning.
84+
*/
85+
@Internal
86+
protected Map<JdbcType, Map<JavaType<?>, BasicType<?>>> getRegistryValues() {
87+
return registryValues;
88+
}
89+
7090
public <J> BasicType<J> getRegisteredType(String key) {
7191
var basicType = typesByName.get( key );
7292
if ( basicType == null ) {

hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/enums/OrdinalEnumTypeTest.java

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,10 @@
1010
import jakarta.persistence.GeneratedValue;
1111
import jakarta.persistence.Id;
1212

13+
import org.hibernate.testing.orm.junit.Jira;
14+
import org.hibernate.type.BasicType;
15+
import org.hibernate.type.BasicTypeRegistry;
16+
import org.hibernate.type.SqlTypes;
1317
import org.hibernate.type.descriptor.JdbcBindingLogging;
1418

1519
import org.hibernate.testing.orm.junit.JiraKey;
@@ -19,10 +23,17 @@
1923
import org.hibernate.testing.orm.junit.MessageKeyWatcher;
2024
import org.hibernate.testing.orm.junit.SessionFactory;
2125
import org.hibernate.testing.orm.junit.SessionFactoryScope;
26+
import org.hibernate.type.descriptor.java.JavaType;
27+
import org.hibernate.type.descriptor.jdbc.JdbcType;
28+
import org.hibernate.type.spi.TypeConfiguration;
2229
import org.junit.jupiter.api.AfterEach;
2330
import org.junit.jupiter.api.BeforeEach;
2431
import org.junit.jupiter.api.Test;
2532

33+
import java.util.List;
34+
import java.util.Map;
35+
36+
import static org.junit.jupiter.api.Assertions.assertEquals;
2637
import static org.junit.jupiter.api.Assertions.assertTrue;
2738

2839
/**
@@ -134,6 +145,55 @@ public void hqlTestEnumQualifiedShortHandSyntaxInPredicate(SessionFactoryScope s
134145
);
135146
}
136147

148+
@Test
149+
@Jira( "https://hibernate.atlassian.net/browse/HHH-19276" )
150+
public void testNoEnumMemoryLeak(SessionFactoryScope scope) {
151+
final List<HairColor> colors = List.of(HairColor.BLACK, HairColor.BROWN);
152+
153+
final TypeConfiguration typeConfiguration = scope.getSessionFactory().getTypeConfiguration();
154+
final TestingBasicTypeRegistry basicTypeRegistry = new TestingBasicTypeRegistry( typeConfiguration.getBasicTypeRegistry() );
155+
final Map<JdbcType, Map<JavaType<?>, BasicType<?>>> registryValues = basicTypeRegistry.getRegistryValues();
156+
final Map<JavaType<?>, BasicType<?>> enumJavaTypeValues = registryValues.get( typeConfiguration.getJdbcTypeRegistry().findDescriptor( SqlTypes.TINYINT ) );
157+
158+
checkEnumTypeRegistryValues( enumJavaTypeValues );
159+
160+
// Basically, multiple runs of this should not result in the creation of additional
161+
// EnumJavaTypes (or BasicTypes for that matter), as was the case before the fix for HHH-19276
162+
for (int counter = 1; counter <= 10; counter++ ) {
163+
scope.inTransaction(
164+
(session) -> {
165+
var result = session.createNativeQuery(
166+
"SELECT * FROM Person WHERE hairColor in (:colors)",
167+
Person.class
168+
)
169+
.setParameter( "colors", colors )
170+
.list();
171+
}
172+
);
173+
}
174+
175+
checkEnumTypeRegistryValues( enumJavaTypeValues );
176+
}
177+
178+
private void checkEnumTypeRegistryValues(Map<JavaType<?>, BasicType<?>> values) {
179+
assertEquals( 2, values.size() );
180+
boolean genderAccountedFor = false;
181+
boolean hairColorAccountedFor = false;
182+
for (JavaType<?> type : values.keySet()) {
183+
genderAccountedFor = genderAccountedFor || type.getTypeName().equals( "org.hibernate.orm.test.mapping.converted.enums.Gender" );
184+
hairColorAccountedFor = hairColorAccountedFor || type.getTypeName().equals( "org.hibernate.orm.test.mapping.converted.enums.HairColor" );
185+
}
186+
assertTrue( genderAccountedFor && hairColorAccountedFor );
187+
}
188+
189+
private <T> JavaType<T> getEnumJavaType(TypeConfiguration typeConfiguration, Class<T> enumJavaType) {
190+
return typeConfiguration.getJavaTypeRegistry().resolveDescriptor(enumJavaType);
191+
}
192+
193+
private <T> BasicType<T> getBasicTypeForEnumJavaType(TypeConfiguration typeConfiguration, Class<T> enumJavaType) {
194+
return typeConfiguration.getBasicTypeRegistry().resolve(enumJavaType, SqlTypes.TINYINT );
195+
}
196+
137197
@Entity(name = "Person")
138198
public static class Person {
139199

@@ -189,4 +249,15 @@ public void setOriginalHairColor(HairColor originalHairColor) {
189249
this.originalHairColor = originalHairColor;
190250
}
191251
}
252+
253+
private static final class TestingBasicTypeRegistry extends BasicTypeRegistry {
254+
private TestingBasicTypeRegistry(BasicTypeRegistry basicTypeRegistry){
255+
super(basicTypeRegistry);
256+
}
257+
258+
@Override
259+
protected Map<JdbcType, Map<JavaType<?>, BasicType<?>>> getRegistryValues() {
260+
return super.getRegistryValues();
261+
}
262+
}
192263
}

0 commit comments

Comments
 (0)