recover previous workaround for problem with MySQL char(n) type

This is needed to remain compatible with schemas we produced in the past,
even though we're nor preferring varchar(1) for storing Java char.

Signed-off-by: Gavin King <gavin@hibernate.org>
This commit is contained in:
Gavin King 2024-10-31 14:07:33 +01:00
parent a389f771bf
commit 633f1012e1
3 changed files with 39 additions and 7 deletions

View File

@ -579,6 +579,15 @@ public abstract class Dialect implements ConversionContext, TypeContributor, Fun
};
}
/**
* Does this dialect strip trailing spaces from values stored
* in columns of type {@code char(n)}?
* MySQL is the main offender here.
*/
public boolean stripsTrailingSpacesFromChar() {
return false;
}
/**
* The SQL type to use in {@code cast( ... as ... )} expressions when
* casting to the target type represented by the given JDBC type code.

View File

@ -284,6 +284,16 @@ public class MySQLDialect extends Dialect {
};
}
/**
* MySQL strips any trailing space character from a
* value stored in a column of type {@code char(n)}.
* @return {@code true}
*/
@Override
public boolean stripsTrailingSpacesFromChar() {
return true;
}
@Override
public boolean useMaterializedLobWhenCapacityExceeded() {
// MySQL has no real concept of LOBs, so we can just use longtext/longblob with the materialized JDBC APIs

View File

@ -63,19 +63,32 @@ public class CharacterJavaType extends AbstractClassJavaType<Character> implemen
if ( value == null ) {
return null;
}
if (value instanceof Character character) {
else if (value instanceof Character character) {
return character;
}
if (value instanceof String string) {
if ( string.length() != 1 ) {
throw new CoercionException( "value must contain exactly one character: '" + string + "'" );
else if (value instanceof String string) {
switch ( string.length() ) {
case 1:
return string.charAt( 0 );
case 0:
if ( options.getDialect().stripsTrailingSpacesFromChar() ) {
// we previously stored char values in char(1) columns on MySQL
// but MySQL strips trailing spaces from the value when read
return ' ';
}
else {
throw new CoercionException( "value does not contain a character: '" + string + "'" );
}
default:
throw new CoercionException( "value contains more than one character: '" + string + "'" );
}
return string.charAt( 0 );
}
if (value instanceof Number number) {
else if (value instanceof Number number) {
return (char) number.shortValue();
}
throw unknownWrap( value.getClass() );
else {
throw unknownWrap( value.getClass() );
}
}
@Override