Reputation: 114
We recently upgraded our application from Spring Boot 2.3.9 to Spring Boot 3.1.0.
This included an upgrade from Hibernate 5.4.28.Final to 6.2.2.Final.
We are running MySql in AWS RDS - 5.7.mysql_aurora.2.11.2 - The default database encoding is latin1.
We noticed after the upgrade that all of the String fields that were annotated as @Nationalized had an issue.
We declared many fields like this:
@Nationalized
private String firstName;
With Hibernate 5.4.28.Final, columns like this would show up in the generated jpa DDL like this:
first_name nvarchar(255)
And then show up in the database like this:
`first_name` varchar(255) CHARACTER SET utf8 DEFAULT NULL,
With Hibernate 6.2.2.final, columns would now show up in the generated jpa DDL like this:
first_name varchar(255)
And then show up in the database like this:
`first_name` varchar(255) DEFAULT NULL,
I tracked this down issue down to the code in org.hibernate.dialect.MySQLDialect lines 330-341
final CapacityDependentDdlType.Builder nvarcharBuilder = CapacityDependentDdlType.builder(
NVARCHAR,
columnType( NCLOB ),
"char",
this
)
.withTypeCapacity( getMaxVarcharLength(), "varchar($l)" )
.withTypeCapacity( maxMediumLobLen, "mediumtext" );
if ( getMaxVarcharLength() < maxLobLen ) {
nvarcharBuilder.withTypeCapacity( maxLobLen, "text" );
}
ddlTypeRegistry.addDescriptor( nvarcharBuilder.build() );
The field objects are correctly being mapped to the field type of NVARCHAR (with type -9), but when the query builder tries to turn that column object into its string representation, it can never pick nvarchar
because that isn't even an option.
The only choices the query mapper has is varchar()
, mediumtext
and text
based upon the mapping above.
I know we can change the default character set and collation of our database to be utf8mb4, and we may pursue that strategy, but I am trying to understand the purpose of this change.
Why would NVARCHAR
only map to varchar
especially when the org.hibernate.dialect.NationalizationSupport for the mysql dialect is EXPLICIT
Upvotes: 2
Views: 363
Reputation: 114
I discussed this with the Hibernate team here
It appears as though the mapping was inadvertently changed because MySql 8 has deprecated nvarchar.
The hibernate team agreed that the mapping should still work for MySql 5.7, and made a change to fix it.
https://github.com/hibernate/hibernate-orm/pull/6827
Instead of mapping nvarcahr -> nvarchar, the fix is to map nvarchar -> varchar character set utf8, which will work on both mysql 5.7 and mysql 8.
Upvotes: 1