HHH-13016 HHH-13199 Force parameter binding for enum literals
Currently, we don't have a way to properly handle enum literals so get back to using parameter binding, which was used before in the "case when" case due to a bug fixed in HHH-13001. Note that this forces the usage of enum literals even at the root of the select clause.
This commit is contained in:
parent
9c72384e1f
commit
624403e65c
|
@ -12,6 +12,7 @@ import org.hibernate.query.criteria.LiteralHandlingMode;
|
|||
import org.hibernate.query.criteria.internal.CriteriaBuilderImpl;
|
||||
import org.hibernate.query.criteria.internal.ParameterRegistry;
|
||||
import org.hibernate.query.criteria.internal.ValueHandlerFactory;
|
||||
import org.hibernate.query.criteria.internal.ValueHandlerFactory.ValueHandler;
|
||||
import org.hibernate.query.criteria.internal.compile.RenderingContext;
|
||||
|
||||
/**
|
||||
|
@ -20,6 +21,7 @@ import org.hibernate.query.criteria.internal.compile.RenderingContext;
|
|||
* @author Steve Ebersole
|
||||
*/
|
||||
public class LiteralExpression<T> extends ExpressionImpl<T> implements Serializable {
|
||||
|
||||
private Object literal;
|
||||
|
||||
@SuppressWarnings({ "unchecked" })
|
||||
|
@ -41,33 +43,40 @@ public class LiteralExpression<T> extends ExpressionImpl<T> implements Serializa
|
|||
return (T) literal;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerParameters(ParameterRegistry registry) {
|
||||
// nothing to do
|
||||
}
|
||||
|
||||
@SuppressWarnings({ "unchecked" })
|
||||
@Override
|
||||
public String render(RenderingContext renderingContext) {
|
||||
// In the case of literals, we currently do not have an easy way to get the value.
|
||||
// That would require some significant infrastructure changes.
|
||||
// For now, we force the normalRender() code path for enums which means we will
|
||||
// always use parameter binding for enum literals.
|
||||
if ( literal instanceof Enum ) {
|
||||
return normalRender( renderingContext, LiteralHandlingMode.BIND );
|
||||
}
|
||||
|
||||
switch ( renderingContext.getClauseStack().getCurrent() ) {
|
||||
case SELECT: {
|
||||
return renderProjection();
|
||||
return renderProjection( renderingContext );
|
||||
}
|
||||
case GROUP: {
|
||||
// technically a literal in the group-by clause
|
||||
// would be a reference to the position of a selection
|
||||
//
|
||||
// but this is what the code used to do...
|
||||
return renderProjection();
|
||||
return renderProjection( renderingContext );
|
||||
}
|
||||
default: {
|
||||
return normalRender( renderingContext );
|
||||
return normalRender( renderingContext, renderingContext.getCriteriaLiteralHandlingMode() );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private String normalRender(RenderingContext renderingContext) {
|
||||
LiteralHandlingMode literalHandlingMode = renderingContext.getCriteriaLiteralHandlingMode();
|
||||
|
||||
private String normalRender(RenderingContext renderingContext, LiteralHandlingMode literalHandlingMode) {
|
||||
switch ( literalHandlingMode ) {
|
||||
case AUTO: {
|
||||
if ( ValueHandlerFactory.isNumeric( literal ) ) {
|
||||
|
@ -86,6 +95,11 @@ public class LiteralExpression<T> extends ExpressionImpl<T> implements Serializa
|
|||
literalValue = renderingContext.getDialect().inlineLiteral( (String) literal );
|
||||
}
|
||||
|
||||
ValueHandler valueHandler = ValueHandlerFactory.determineAppropriateHandler( (Class) literal.getClass() );
|
||||
if ( valueHandler == null ) {
|
||||
return bindLiteral( renderingContext );
|
||||
}
|
||||
|
||||
return ValueHandlerFactory.determineAppropriateHandler( (Class) literal.getClass() ).render( literalValue );
|
||||
}
|
||||
default: {
|
||||
|
@ -94,10 +108,15 @@ public class LiteralExpression<T> extends ExpressionImpl<T> implements Serializa
|
|||
}
|
||||
}
|
||||
|
||||
private String renderProjection() {
|
||||
private String renderProjection(RenderingContext renderingContext) {
|
||||
// some drivers/servers do not like parameters in the select clause
|
||||
final ValueHandlerFactory.ValueHandler handler =
|
||||
ValueHandlerFactory.determineAppropriateHandler( literal.getClass() );
|
||||
|
||||
if ( handler == null ) {
|
||||
return normalRender( renderingContext, LiteralHandlingMode.BIND );
|
||||
}
|
||||
|
||||
if ( ValueHandlerFactory.isCharacter( literal ) ) {
|
||||
return '\'' + handler.render( literal ) + '\'';
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue