HHH-15278 NPE when NULL is used in the projection

This commit is contained in:
Andrea Boriero 2022-05-17 12:03:22 +02:00 committed by Andrea Boriero
parent 3251d5e9d0
commit 1ae61b3388
3 changed files with 41 additions and 9 deletions

View File

@ -173,9 +173,12 @@ import org.hibernate.sql.exec.spi.JdbcUpdate;
import org.hibernate.sql.results.internal.SqlSelectionImpl; import org.hibernate.sql.results.internal.SqlSelectionImpl;
import org.hibernate.sql.results.jdbc.internal.JdbcValuesMappingProducerStandard; import org.hibernate.sql.results.jdbc.internal.JdbcValuesMappingProducerStandard;
import org.hibernate.type.BasicType; import org.hibernate.type.BasicType;
import org.hibernate.type.SqlTypes;
import org.hibernate.type.StandardBasicTypes; import org.hibernate.type.StandardBasicTypes;
import org.hibernate.type.descriptor.WrapperOptions; import org.hibernate.type.descriptor.WrapperOptions;
import org.hibernate.type.descriptor.jdbc.JdbcLiteralFormatter; import org.hibernate.type.descriptor.jdbc.JdbcLiteralFormatter;
import org.hibernate.type.descriptor.sql.DdlType;
import org.hibernate.type.descriptor.sql.spi.DdlTypeRegistry;
import static org.hibernate.query.sqm.TemporalUnit.NANOSECOND; import static org.hibernate.query.sqm.TemporalUnit.NANOSECOND;
import static org.hibernate.sql.ast.SqlTreePrinter.logSqlAst; import static org.hibernate.sql.ast.SqlTreePrinter.logSqlAst;
@ -4293,10 +4296,17 @@ public abstract class AbstractSqlAstTranslator<T extends JdbcOperation> implemen
} }
else { else {
final SqlExpressible expressionType = (SqlExpressible) castTarget.getExpressionType(); final SqlExpressible expressionType = (SqlExpressible) castTarget.getExpressionType();
final DdlTypeRegistry ddlTypeRegistry = getSessionFactory().getTypeConfiguration().getDdlTypeRegistry();
DdlType ddlType = ddlTypeRegistry
.getDescriptor( expressionType.getJdbcMapping().getJdbcType().getDefaultSqlTypeCode() );
if ( ddlType == null ) {
// this may happen when selecting a null value like `SELECT null from ...`
// some dbs need the value to be cast so not knowing the real type we fall back to INTEGER
ddlType = ddlTypeRegistry.getDescriptor( SqlTypes.INTEGER );
}
appendSql( appendSql(
sessionFactory.getTypeConfiguration().getDdlTypeRegistry() ddlType.getCastTypeName(
.getDescriptor( expressionType.getJdbcMapping().getJdbcType().getDefaultSqlTypeCode() )
.getCastTypeName(
expressionType, expressionType,
castTarget.getLength(), castTarget.getLength(),
castTarget.getPrecision(), castTarget.getPrecision(),

View File

@ -32,4 +32,9 @@ public class NullType extends JavaObjectType {
public String getName() { public String getName() {
return "null"; return "null";
} }
@Override
protected boolean registerUnderJavaType() {
return false;
}
} }

View File

@ -8,6 +8,7 @@ package org.hibernate.type.descriptor.jdbc;
import java.sql.CallableStatement; import java.sql.CallableStatement;
import java.sql.PreparedStatement; import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException; import java.sql.SQLException;
import java.sql.Types; import java.sql.Types;
@ -34,9 +35,25 @@ public class NullJdbcType implements JdbcType {
@Override @Override
public <X> ValueExtractor<X> getExtractor(JavaType<X> javaType) { public <X> ValueExtractor<X> getExtractor(JavaType<X> javaType) {
return new BasicExtractor<X>(javaType, this ) {
@Override
protected X doExtract(ResultSet rs, int paramIndex, WrapperOptions options) throws SQLException {
return null; return null;
} }
@Override
protected X doExtract(CallableStatement statement, int index, WrapperOptions options) throws SQLException {
return null;
}
@Override
protected X doExtract(CallableStatement statement, String name, WrapperOptions options)
throws SQLException {
return null;
}
};
}
@Override @Override
public <X> ValueBinder<X> getBinder(JavaType<X> javaType) { public <X> ValueBinder<X> getBinder(JavaType<X> javaType) {
return new BasicBinder<>( javaType, this ) { return new BasicBinder<>( javaType, this ) {