最近将我的项目升级到 Spring boot 3 和 Hibernate 6.1.5(从 5.x)。我正在努力迁移我们用来扩展的不同方言。
覆盖方言的方式已更改,因此我从此迁移了我的 H2 方言扩展(hibernate 5):
public class ExtendedH2Dialect extends H2Dialect {
@Override
public String renderOrderByElement(String expression, String collation, String order, NullPrecedence nulls) {
return super.renderOrderByElement(expression, collation, order, NullPrecedence.LAST);
}
}
对此(休眠6):
public class ExtendedH2Dialect extends H2Dialect {
public ExtendedH2Dialect(DialectResolutionInfo info) {
super(info);
}
@Override
public NullOrdering getNullOrdering() {
return NullOrdering.LAST;
}
}
但是 JPA 查询似乎完全忽略了空排序。 举个例子,如果我在 hibernate 5 中这样做:
entityManager.createQuery("from CityEntity order by name").getResultList();
生成的查询是:
从 city_entity cityentity0_ order by cityentity0_.name 最后选择 cityentity0_.id 作为 id1_0_,cityentity0_.name 作为 name2_0_
现在使用 Hibernate 6:
从 city_entity c1_0 按 c1_0.name 顺序选择 c1_0.id,c1_0.name
我的自定义方言仍然注册为“HHH000400:使用方言:com.example.demoextendh2.ExtendedH2Dialect”。
我上传了一个最小的可复制项目这里
我做错了什么吗?找不到很多关于自定义方言迁移的文档。
看起来需要在项目的配置中设置默认排序属性(application.yml,或者其他什么):
hibernate.order_by.default_null_ordering:'最后'
在你的方言中,只需要在supportsNullPrecedence()调用上返回true,但情况应该已经是这样了。 (不要重写 getNullOrdering() 方法)。
这解决了我们的问题。似乎在决定是否需要添加空值排序时,AbstractSqlAstTranslator 会比较配置中所需的默认排序和方言提供的排序。如果它们不同并且方言支持空排序,它只会添加显式空排序。意思是,如果方言已经最后使用空值排序并且您最后需要空值,则休眠知道它不需要添加显式排序,因为它应该自动获取它(根据方言)