Skip to content

Commit 14e46e5

Browse files
committed
HHH-20265 Resolve type variables to bounds when no concrete type is given
1 parent 294bc15 commit 14e46e5

2 files changed

Lines changed: 58 additions & 3 deletions

File tree

hibernate-core/src/main/java/org/hibernate/internal/util/GenericsHelper.java

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,12 +50,22 @@ public static Type actualInheritedMemberType(Class<?> subclass, Member superMemb
5050
private static Map<TypeVariable<?>, Type> collectTypeArguments(
5151
Class<?> subclass, Member superMember) {
5252
final var superclass = superMember.getDeclaringClass();
53-
final var typeArguments = typeArguments( superclass, subclass );
5453
final var typeParameters = superclass.getTypeParameters();
5554
final Map<TypeVariable<?>, Type> typeMap =
5655
new HashMap<>( typeParameters.length );
57-
for ( int i = 0; i < typeParameters.length; i++ ) {
58-
typeMap.put( typeParameters[i], typeArguments[i] );
56+
57+
// There is no context to resolve the type variables if the subclass is the same as the superclass,
58+
// so just take the type parameter bounds instead
59+
if ( subclass == superclass ) {
60+
for ( var typeParameter : typeParameters ) {
61+
typeMap.put( typeParameter, typeParameter.getBounds()[0] );
62+
}
63+
}
64+
else {
65+
final var typeArguments = typeArguments( superclass, subclass );
66+
for ( int i = 0; i < typeParameters.length; i++ ) {
67+
typeMap.put( typeParameters[i], typeArguments[i] );
68+
}
5969
}
6070
return typeMap;
6171
}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
/*
2+
* SPDX-License-Identifier: Apache-2.0
3+
* Copyright Red Hat Inc. and Hibernate Authors
4+
*/
5+
package org.hibernate.internal.util;
6+
7+
import org.hibernate.testing.orm.junit.Jira;
8+
import org.junit.jupiter.api.Test;
9+
10+
import java.lang.reflect.Type;
11+
import jakarta.persistence.*;
12+
13+
import static org.assertj.core.api.Assertions.assertThat;
14+
15+
public class GenericsHelperTest {
16+
@Test
17+
@Jira("https://hibernate.atlassian.net/browse/HHH-20265")
18+
public void testChainedTypeVariable() throws Exception {
19+
Type t = GenericsHelper.actualInheritedMemberType(
20+
BaseLibraryEntity.class,
21+
BaseLibraryEntity.class.getDeclaredField( "processed" )
22+
);
23+
24+
assertThat(t).isEqualTo(boolean.class);
25+
}
26+
27+
@MappedSuperclass
28+
static abstract class BaseEntity<T> {
29+
}
30+
31+
@MappedSuperclass
32+
static abstract class BaseReadableEntity<T> extends BaseEntity<T> {
33+
}
34+
35+
@MappedSuperclass
36+
static abstract class BaseLibraryEntity<T> extends BaseReadableEntity<T> {
37+
private boolean processed;
38+
}
39+
40+
@Entity
41+
static class Book extends BaseLibraryEntity<String> {
42+
@Id
43+
private String id;
44+
}
45+
}

0 commit comments

Comments
 (0)