improve error reporting in DynamicInstantiation stuff
This commit is contained in:
parent
4c489eedbd
commit
addd88000c
|
@ -39,9 +39,7 @@ public class DynamicInstantiationAssemblerConstructorImpl<R> implements DomainRe
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public R assemble(
|
public R assemble(RowProcessingState rowProcessingState, JdbcValuesSourceProcessingOptions options) {
|
||||||
RowProcessingState rowProcessingState,
|
|
||||||
JdbcValuesSourceProcessingOptions options) {
|
|
||||||
final int numberOfArgs = argumentReaders.size();
|
final int numberOfArgs = argumentReaders.size();
|
||||||
Object[] args = new Object[ numberOfArgs ];
|
Object[] args = new Object[ numberOfArgs ];
|
||||||
for ( int i = 0; i < numberOfArgs; i++ ) {
|
for ( int i = 0; i < numberOfArgs; i++ ) {
|
||||||
|
@ -52,10 +50,12 @@ public class DynamicInstantiationAssemblerConstructorImpl<R> implements DomainRe
|
||||||
return targetConstructor.newInstance( args );
|
return targetConstructor.newInstance( args );
|
||||||
}
|
}
|
||||||
catch (InvocationTargetException e) {
|
catch (InvocationTargetException e) {
|
||||||
throw new InstantiationException( "Error performing dynamic instantiation : " + targetConstructor.getDeclaringClass().getName(), e.getCause() );
|
throw new InstantiationException( "Error instantiating class '"
|
||||||
|
+ targetConstructor.getDeclaringClass().getName() + "'", e.getCause() );
|
||||||
}
|
}
|
||||||
catch (Exception e) {
|
catch (Exception e) {
|
||||||
throw new InstantiationException( "Error performing dynamic instantiation : " + targetConstructor.getDeclaringClass().getName(), e );
|
throw new InstantiationException( "Error instantiating class '"
|
||||||
|
+ targetConstructor.getDeclaringClass().getName() + "'", e );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -78,8 +78,8 @@ public class DynamicInstantiationAssemblerInjectionImpl<T> implements DomainResu
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
throw new InstantiationException(
|
throw new InstantiationException(
|
||||||
"Unable to determine dynamic instantiation injection strategy for " +
|
"Cannot set field '" + argumentReader.getAlias()
|
||||||
targetJavaType.getName() + "#" + argumentReader.getAlias()
|
+ "' to instantiate '" + targetJavaType.getName() + "'"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -114,8 +114,14 @@ public class DynamicInstantiationAssemblerInjectionImpl<T> implements DomainResu
|
||||||
@Override
|
@Override
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public T assemble(RowProcessingState rowProcessingState, JdbcValuesSourceProcessingOptions options) {
|
public T assemble(RowProcessingState rowProcessingState, JdbcValuesSourceProcessingOptions options) {
|
||||||
|
final T result;
|
||||||
try {
|
try {
|
||||||
final T result = target.getJavaTypeClass().newInstance();
|
result = target.getJavaTypeClass().newInstance();
|
||||||
|
}
|
||||||
|
catch (IllegalAccessException | InstantiationException | java.lang.InstantiationException e) {
|
||||||
|
throw new InstantiationException( "Error instantiating class '"
|
||||||
|
+ target.getJavaType().getTypeName() + "' using default constructor", e );
|
||||||
|
}
|
||||||
for ( BeanInjection beanInjection : beanInjections ) {
|
for ( BeanInjection beanInjection : beanInjections ) {
|
||||||
beanInjection.getBeanInjector().inject(
|
beanInjection.getBeanInjector().inject(
|
||||||
result,
|
result,
|
||||||
|
@ -124,8 +130,4 @@ public class DynamicInstantiationAssemblerInjectionImpl<T> implements DomainResu
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
catch (IllegalAccessException | InstantiationException | java.lang.InstantiationException e) {
|
|
||||||
throw new InstantiationException( "Could not call default constructor [" + target.getJavaType().getTypeName() + "]", e );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,6 @@ import java.util.Set;
|
||||||
|
|
||||||
import org.hibernate.internal.util.StringHelper;
|
import org.hibernate.internal.util.StringHelper;
|
||||||
import org.hibernate.query.sqm.DynamicInstantiationNature;
|
import org.hibernate.query.sqm.DynamicInstantiationNature;
|
||||||
import org.hibernate.query.sqm.tree.expression.Compatibility;
|
|
||||||
import org.hibernate.sql.results.graph.AssemblerCreationState;
|
import org.hibernate.sql.results.graph.AssemblerCreationState;
|
||||||
import org.hibernate.sql.results.graph.DomainResultAssembler;
|
import org.hibernate.sql.results.graph.DomainResultAssembler;
|
||||||
import org.hibernate.sql.results.graph.FetchParentAccess;
|
import org.hibernate.sql.results.graph.FetchParentAccess;
|
||||||
|
@ -25,6 +24,9 @@ import org.hibernate.type.descriptor.java.JavaType;
|
||||||
|
|
||||||
import org.jboss.logging.Logger;
|
import org.jboss.logging.Logger;
|
||||||
|
|
||||||
|
import static java.util.stream.Collectors.toList;
|
||||||
|
import static org.hibernate.query.sqm.tree.expression.Compatibility.areAssignmentCompatible;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Steve Ebersole
|
* @author Steve Ebersole
|
||||||
*/
|
*/
|
||||||
|
@ -90,16 +92,15 @@ public class DynamicInstantiationResultImpl<R> implements DynamicInstantiationRe
|
||||||
else {
|
else {
|
||||||
if ( !aliases.add( argumentAlias ) ) {
|
if ( !aliases.add( argumentAlias ) ) {
|
||||||
duplicatedAliases.add( argumentAlias );
|
duplicatedAliases.add( argumentAlias );
|
||||||
log.debugf( "Query defined duplicate resultVariable encountered multiple declarations of [%s]",
|
log.debugf(
|
||||||
|
"Query defined duplicate resultVariable encountered multiple declarations of [%s]",
|
||||||
argumentAlias
|
argumentAlias
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
areAnyArgumentsAliased = true;
|
areAnyArgumentsAliased = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
argumentReaders.add(
|
argumentReaders.add( argumentResult.createResultAssembler( parentAccess, creationState ) );
|
||||||
argumentResult.createResultAssembler( parentAccess, creationState )
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -124,34 +125,28 @@ public class DynamicInstantiationResultImpl<R> implements DynamicInstantiationRe
|
||||||
if ( log.isDebugEnabled() && areAnyArgumentsAliased ) {
|
if ( log.isDebugEnabled() && areAnyArgumentsAliased ) {
|
||||||
log.debug( "One or more arguments for List dynamic instantiation (`new list(...)`) specified an alias; ignoring" );
|
log.debug( "One or more arguments for List dynamic instantiation (`new list(...)`) specified an alias; ignoring" );
|
||||||
}
|
}
|
||||||
return (DomainResultAssembler<R>) new DynamicInstantiationAssemblerListImpl(
|
return (DomainResultAssembler<R>)
|
||||||
(JavaType<List<?>>) javaType,
|
new DynamicInstantiationAssemblerListImpl( (JavaType<List<?>>) javaType, argumentReaders );
|
||||||
argumentReaders
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
else if ( nature == DynamicInstantiationNature.MAP ) {
|
else if ( nature == DynamicInstantiationNature.MAP ) {
|
||||||
if ( ! areAllArgumentsAliased ) {
|
if ( ! areAllArgumentsAliased ) {
|
||||||
throw new IllegalStateException( "Map dynamic instantiation contained one or more arguments with no alias" );
|
throw new IllegalStateException( "Map instantiation contained one or more arguments with no alias" );
|
||||||
}
|
}
|
||||||
if ( !duplicatedAliases.isEmpty() ) {
|
if ( !duplicatedAliases.isEmpty() ) {
|
||||||
throw new IllegalStateException(
|
throw new IllegalStateException(
|
||||||
"Map dynamic instantiation contained arguments with duplicated aliases [" + StringHelper.join( ",", duplicatedAliases ) + "]"
|
"Map instantiation has arguments with duplicate aliases ["
|
||||||
|
+ StringHelper.join( ",", duplicatedAliases ) + "]"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return (DomainResultAssembler<R>) new DynamicInstantiationAssemblerMapImpl(
|
return (DomainResultAssembler<R>)
|
||||||
(JavaType<Map<?,?>>) javaType,
|
new DynamicInstantiationAssemblerMapImpl( (JavaType<Map<?,?>>) javaType, argumentReaders );
|
||||||
argumentReaders
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// find a constructor matching argument types
|
// find a constructor matching argument types
|
||||||
constructor_loop:
|
constructor_loop:
|
||||||
for ( Constructor<?> constructor : javaType.getJavaTypeClass().getDeclaredConstructors() ) {
|
for ( Constructor<?> constructor : javaType.getJavaTypeClass().getDeclaredConstructors() ) {
|
||||||
final Type[] genericParameterTypes = constructor.getGenericParameterTypes();
|
final Type[] genericParameterTypes = constructor.getGenericParameterTypes();
|
||||||
if ( genericParameterTypes.length != argumentReaders.size() ) {
|
if ( genericParameterTypes.length == argumentReaders.size() ) {
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
for ( int i = 0; i < argumentReaders.size(); i++ ) {
|
for ( int i = 0; i < argumentReaders.size(); i++ ) {
|
||||||
final ArgumentReader<?> argumentReader = argumentReaders.get( i );
|
final ArgumentReader<?> argumentReader = argumentReaders.get( i );
|
||||||
final JavaType<?> argumentTypeDescriptor = creationState.getSqlAstCreationContext()
|
final JavaType<?> argumentTypeDescriptor = creationState.getSqlAstCreationContext()
|
||||||
|
@ -160,11 +155,7 @@ public class DynamicInstantiationResultImpl<R> implements DynamicInstantiationRe
|
||||||
.getJavaTypeRegistry()
|
.getJavaTypeRegistry()
|
||||||
.resolveDescriptor( genericParameterTypes[i] );
|
.resolveDescriptor( genericParameterTypes[i] );
|
||||||
|
|
||||||
final boolean assignmentCompatible = Compatibility.areAssignmentCompatible(
|
if ( !areAssignmentCompatible( argumentTypeDescriptor, argumentReader.getAssembledJavaType() ) ) {
|
||||||
argumentTypeDescriptor,
|
|
||||||
argumentReader.getAssembledJavaType()
|
|
||||||
);
|
|
||||||
if ( !assignmentCompatible ) {
|
|
||||||
if ( log.isDebugEnabled() ) {
|
if ( log.isDebugEnabled() ) {
|
||||||
log.debugf(
|
log.debugf(
|
||||||
"Skipping constructor for dynamic-instantiation match due to argument mismatch [%s] : %s -> %s",
|
"Skipping constructor for dynamic-instantiation match due to argument mismatch [%s] : %s -> %s",
|
||||||
|
@ -179,11 +170,8 @@ public class DynamicInstantiationResultImpl<R> implements DynamicInstantiationRe
|
||||||
|
|
||||||
constructor.setAccessible( true );
|
constructor.setAccessible( true );
|
||||||
//noinspection rawtypes
|
//noinspection rawtypes
|
||||||
return new DynamicInstantiationAssemblerConstructorImpl(
|
return new DynamicInstantiationAssemblerConstructorImpl( constructor, javaType, argumentReaders );
|
||||||
constructor,
|
}
|
||||||
javaType,
|
|
||||||
argumentReaders
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( log.isDebugEnabled() ) {
|
if ( log.isDebugEnabled() ) {
|
||||||
|
@ -195,20 +183,27 @@ public class DynamicInstantiationResultImpl<R> implements DynamicInstantiationRe
|
||||||
|
|
||||||
if ( ! areAllArgumentsAliased ) {
|
if ( ! areAllArgumentsAliased ) {
|
||||||
throw new IllegalStateException(
|
throw new IllegalStateException(
|
||||||
"Could not determine appropriate instantiation strategy - no matching constructor found and one or more arguments did not define alias for bean-injection"
|
"Cannot instantiate class '" + javaType.getJavaType().getTypeName() + "'"
|
||||||
|
+ " (it has no constructor with signature " + signature()
|
||||||
|
+ ", and not every argument has an alias)"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if ( !duplicatedAliases.isEmpty() ) {
|
if ( !duplicatedAliases.isEmpty() ) {
|
||||||
throw new IllegalStateException(
|
throw new IllegalStateException(
|
||||||
"Could not determine appropriate instantiation strategy - no matching constructor found and arguments defined duplicated aliases [" +
|
"Cannot instantiate class '" + javaType.getJavaType().getTypeName() + "'"
|
||||||
StringHelper.join( ",", duplicatedAliases ) + "] for bean-injection"
|
+ " (it has no constructor with signature " + signature()
|
||||||
|
+ ", and has arguments with duplicate aliases ["
|
||||||
|
+ StringHelper.join( ",", duplicatedAliases ) + "])"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return new DynamicInstantiationAssemblerInjectionImpl<>(
|
return new DynamicInstantiationAssemblerInjectionImpl<>( javaType, argumentReaders );
|
||||||
javaType,
|
|
||||||
argumentReaders
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private List<String> signature() {
|
||||||
|
return argumentResults.stream()
|
||||||
|
.map( adt -> adt.getResultJavaType().getJavaType().getTypeName() )
|
||||||
|
.collect( toList() );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue