用@Nationalized标记的列未Map到Hibernate 6.2.2和MySql 5.7中正确的列类型

gfttwv5a  于 2023-06-23  发布在  Mysql
关注(0)|答案(1)|浏览(284)

我们最近将我们的应用程序从Sping Boot 2.3.9升级到Spring Boot 3.1.0。
这包括从Hibernate 5.4.28.Final升级到6.2.2.Final。
我们正在AWS RDS - 5.7.mysql_aurora.2.11.2中运行MySql-默认数据库编码为latin 1。
升级后我们注意到,所有注解为@Nationalized的String字段都有问题。
我们声明了许多这样的字段:

@Nationalized
private String firstName;

升级前

在Hibernate 5.4.28.Final中,这样的列将在生成的jpa DDL中显示为:

first_name nvarchar(255)

然后在数据库中显示如下:

`first_name` varchar(255) CHARACTER SET utf8 DEFAULT NULL,

升级后

使用Hibernate 6.2.2.final,列现在将显示在生成的jpa DDL中,如下所示:

first_name varchar(255)

然后在数据库中显示如下:

`first_name` varchar(255) DEFAULT NULL,

我将这个问题追踪到org.hibernate.dialect.MySQLDialect第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() );

字段对象被正确地Map到NVARCHAR的字段类型(类型为-9),但是当查询构建器试图将该列对象转换为字符串表示时,它永远不能选择nvarchar,因为这甚至不是一个选项。
根据上面的Map,查询Map器仅有的选择是varchar()mediumtexttext
我知道我们可以将数据库的默认字符集和排序规则更改为utf8 mb 4,我们可能会采用这种策略,但我正在尝试理解这种更改的目的。
为什么NVARCHAR只Map到varchar,特别是当org.hibernate.dialect.NationalizationSupport为mysql方言的时候是EXPLICIT

13z8s7eq

13z8s7eq1#

我在这里与Hibernate团队讨论了这个问题
https://hibernate.zulipchat.com/#narrow/stream/132096-hibernate-user/topic/Hibernate.205.20to.206.20Migration.20Issue
看起来好像Map被无意中更改了,因为MySql 8已经弃用了nvarchar。
hibernate团队同意Map仍然适用于MySql 5.7,并进行了修改以修复它。
https://github.com/hibernate/hibernate-orm/pull/6827
而不是Mapnvarcahr -> nvarchar,修复是Mapnvarchar -> varchar字符集utf8,这将在mysql 5.7和mysql 8上工作。

相关问题