hibernate-orm
hibernate-orm copied to clipboard
HHH-16809 - Add JavaType#createArray
https://hibernate.atlassian.net/browse/HHH-16809
@sebersole Do you remember the problem that prevented this PR to move further towards completion? I'm afraid I don't...
Regarding the (non-default) implementation of createTypedArray(), of course the most reliable and most performant solution would be to implement the method for every single JavaType.
But if that's not practical, that's not strictly necessary as far as Quarkus is concerned. From what I can see JavaType instances are created about when Hibernate ORM creates the Metadata, so it could be enough to perform reflective operations in the constructor of AbstractClassJavaType. For example something like this could work for Quarkus (I'd need to test of course):
public abstract class AbstractClassJavaType<T> implements BasicJavaType<T>, Serializable {
private final Class<T> type;
private final MutabilityPlan<T> mutabilityPlan;
private final Comparator<T> comparator;
private final Class<T[]> arrayType;
private final Constructor<T[]> arrayTypeConstructor;
protected AbstractClassJavaType(
Class<? extends T> type,
MutabilityPlan<? extends T> mutabilityPlan,
Comparator<? extends T> comparator) {
this.type = (Class<T>) type;
this.mutabilityPlan = (MutabilityPlan<T>) mutabilityPlan;
this.comparator = (Comparator<T>) comparator;
// Reflective operation, but happens during metadata building
// (before native compilation in Quarkus) so it's fine
this.arrayType = (Class<T[]>) Array.newInstance( getJavaTypeClass(), 0 ).getClass();
this.arrayTypeConstructor = arrayType.getConstructor( int.class );
}
@Override
public T[] createTypedArray(int numberOfElements) {
return arrayTypeConstructor.newInstance( numberOfElements );
}
@Override
public Class<T[]> getArrayType() {
return arrayType;
}
This solution would probably lead to some overhead, since I suspect JavaType instances live on the heap as long as the Metadata/SessionFactory are there, so GraalVM would probably consider all types can potentially be reached and wouldn't eliminate any dead code. But it should work, so it's a reasonable trade-off if implementing createTypedArray() for every single JavaType subclass is not an option.
Not sure we can do anything about org.hibernate.type.descriptor.java.AbstractJavaType though... We'd have to implement methods for each subclass.
I think we concluded that we'd like to try using Object[] for everything instead of specialized arrays. In the meantime, Quarkus should register array types for all basic types for reflection.
The main problem I ran into was JavaType descriptors for primitive/wrapper types. IntegerJavaType e.g. handles both int and Integer. So a proper implementation would need to know which to use, which would need to get passed in - which gets fugly