Skip to content

Commit 633f101

Browse files
committed
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 <[email protected]>
1 parent a389f77 commit 633f101

File tree

3 files changed

+39
-7
lines changed

3 files changed

+39
-7
lines changed

hibernate-core/src/main/java/org/hibernate/dialect/Dialect.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -579,6 +579,15 @@ protected String columnType(int sqlTypeCode) {
579579
};
580580
}
581581

582+
/**
583+
* Does this dialect strip trailing spaces from values stored
584+
* in columns of type {@code char(n)}?
585+
* MySQL is the main offender here.
586+
*/
587+
public boolean stripsTrailingSpacesFromChar() {
588+
return false;
589+
}
590+
582591
/**
583592
* The SQL type to use in {@code cast( ... as ... )} expressions when
584593
* casting to the target type represented by the given JDBC type code.

hibernate-core/src/main/java/org/hibernate/dialect/MySQLDialect.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -284,6 +284,16 @@ protected String columnType(int sqlTypeCode) {
284284
};
285285
}
286286

287+
/**
288+
* MySQL strips any trailing space character from a
289+
* value stored in a column of type {@code char(n)}.
290+
* @return {@code true}
291+
*/
292+
@Override
293+
public boolean stripsTrailingSpacesFromChar() {
294+
return true;
295+
}
296+
287297
@Override
288298
public boolean useMaterializedLobWhenCapacityExceeded() {
289299
// MySQL has no real concept of LOBs, so we can just use longtext/longblob with the materialized JDBC APIs

hibernate-core/src/main/java/org/hibernate/type/descriptor/java/CharacterJavaType.java

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -63,19 +63,32 @@ public <X> Character wrap(X value, WrapperOptions options) {
6363
if ( value == null ) {
6464
return null;
6565
}
66-
if (value instanceof Character character) {
66+
else if (value instanceof Character character) {
6767
return character;
6868
}
69-
if (value instanceof String string) {
70-
if ( string.length() != 1 ) {
71-
throw new CoercionException( "value must contain exactly one character: '" + string + "'" );
69+
else if (value instanceof String string) {
70+
switch ( string.length() ) {
71+
case 1:
72+
return string.charAt( 0 );
73+
case 0:
74+
if ( options.getDialect().stripsTrailingSpacesFromChar() ) {
75+
// we previously stored char values in char(1) columns on MySQL
76+
// but MySQL strips trailing spaces from the value when read
77+
return ' ';
78+
}
79+
else {
80+
throw new CoercionException( "value does not contain a character: '" + string + "'" );
81+
}
82+
default:
83+
throw new CoercionException( "value contains more than one character: '" + string + "'" );
7284
}
73-
return string.charAt( 0 );
7485
}
75-
if (value instanceof Number number) {
86+
else if (value instanceof Number number) {
7687
return (char) number.shortValue();
7788
}
78-
throw unknownWrap( value.getClass() );
89+
else {
90+
throw unknownWrap( value.getClass() );
91+
}
7992
}
8093

8194
@Override

0 commit comments

Comments
 (0)