Skip to content

Commit b16c6a0

Browse files
committed
HHH-18649 populate EntityGraph in static metamodel
1 parent d026887 commit b16c6a0

File tree

3 files changed

+283
-237
lines changed

3 files changed

+283
-237
lines changed
Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
/*
2+
* SPDX-License-Identifier: LGPL-2.1-or-later
3+
* Copyright Red Hat Inc. and Hibernate Authors
4+
*/
5+
package org.hibernate.metamodel.internal;
6+
7+
import org.hibernate.AssertionFailure;
8+
import org.hibernate.boot.model.NamedEntityGraphDefinition;
9+
import org.hibernate.boot.query.NamedQueryDefinition;
10+
import org.hibernate.internal.CoreLogging;
11+
import org.hibernate.internal.CoreMessageLogger;
12+
import org.hibernate.internal.util.ReflectHelper;
13+
import org.hibernate.metamodel.model.domain.JpaMetamodel;
14+
15+
import java.lang.reflect.Field;
16+
17+
import static java.lang.Character.charCount;
18+
19+
public class InjectionHelper {
20+
private static final CoreMessageLogger log = CoreLogging.messageLogger( MetadataContext.class );
21+
22+
public static void injectEntityGraph(
23+
NamedEntityGraphDefinition definition,
24+
Class<?> metamodelClass,
25+
JpaMetamodel jpaMetamodel) {
26+
try {
27+
injectField(
28+
metamodelClass,
29+
'_' + javaIdentifier( definition.getRegisteredName() ),
30+
jpaMetamodel.findEntityGraphByName( definition.getRegisteredName() ),
31+
false
32+
);
33+
}
34+
catch ( NoSuchFieldException e ) {
35+
// ignore
36+
}
37+
}
38+
39+
public static void injectTypedQueryReference(NamedQueryDefinition<?> definition, Class<?> metamodelClass) {
40+
try {
41+
injectField(
42+
metamodelClass,
43+
'_' + javaIdentifier( definition.getRegistrationName() ) + '_',
44+
definition,
45+
false
46+
);
47+
}
48+
catch ( NoSuchFieldException e ) {
49+
// ignore
50+
}
51+
}
52+
53+
public static String javaIdentifier(String name) {
54+
final StringBuilder result = new StringBuilder();
55+
int position = 0;
56+
while ( position < name.length() ) {
57+
final int codePoint = name.codePointAt( position );
58+
if ( Character.isJavaIdentifierPart(codePoint) ) {
59+
result.appendCodePoint( codePoint );
60+
}
61+
else {
62+
result.append('_');
63+
}
64+
position += charCount( codePoint );
65+
}
66+
return result.toString();
67+
}
68+
69+
public static void injectField(
70+
Class<?> metamodelClass, String name, Object model,
71+
boolean allowNonDeclaredFieldReference)
72+
throws NoSuchFieldException {
73+
final Field field = allowNonDeclaredFieldReference
74+
? metamodelClass.getField(name)
75+
: metamodelClass.getDeclaredField(name);
76+
try {
77+
// should be public anyway, but to be sure...
78+
ReflectHelper.ensureAccessibility( field );
79+
field.set( null, model);
80+
}
81+
catch (IllegalAccessException e) {
82+
// todo : exception type?
83+
throw new AssertionFailure(
84+
"Unable to inject static metamodel attribute : " + metamodelClass.getName() + '#' + name,
85+
e
86+
);
87+
}
88+
catch (IllegalArgumentException e) {
89+
// most likely a mismatch in the type we are injecting and the defined field; this represents a
90+
// mismatch in how the annotation processor interpreted the attribute and how our metamodel
91+
// and/or annotation binder did.
92+
93+
// This is particularly the case as arrays are not handled properly by the StaticMetamodel generator
94+
95+
// throw new AssertionFailure(
96+
// "Illegal argument on static metamodel field injection : " + metamodelClass.getName() + '#' + name
97+
// + "; expected type : " + attribute.getClass().getName()
98+
// + "; encountered type : " + field.getType().getName()
99+
// );
100+
log.illegalArgumentOnStaticMetamodelFieldInjection(
101+
metamodelClass.getName(),
102+
name,
103+
model.getClass().getName(),
104+
field.getType().getName()
105+
);
106+
}
107+
}
108+
109+
}

0 commit comments

Comments
 (0)