Hibernate 6.4:如何在TypeContributor中按Dialect条件注册自定义类型
在Hibernate 6.4中通过TypeContributor根据Dialect条件注册自定义类型
问题场景
我有一个通过Java Service Loader机制加载的Hibernate TypeContributor实现类,代码如下:
public class MyTypeContributor implements TypeContributor { @Override public void contribute(TypeContributions typeContributions, ServiceRegistry serviceRegistry) { // if Dialect is ... then ... } }
现在需要根据当前Dialect的条件注册自定义类型,但contribute方法中无法直接获取Dialect,且我不想创建新的Dialect。
对比FunctionContributions,函数贡献时能轻松获取Dialect信息,但类型贡献却做不到,这点比较奇怪。
我曾尝试模仿FunctionContributions的方式获取Dialect,但调用getDialect()时抛出空指针异常:
public class MyTypeContributor implements TypeContributor { @Override public void contribute(TypeContributions typeContributions, ServiceRegistry serviceRegistry) { Dialect dialect = typeContributions .getTypeConfiguration() .getCurrentBaseSqlTypeIndicators() .getDialect(); } }
目前有一个可行方案(感谢zforgo),但不确定JdbcServices是否始终可用:
public class MyTypeContributor implements TypeContributor { @Override public void contribute(TypeContributions typeContributions, ServiceRegistry serviceRegistry) { Dialect dialect = serviceRegistry .getService(JdbcServices.class) // 可能返回null .getDialect(); } }
解决方案分析与优化
可行方案的可靠性说明
通过ServiceRegistry获取JdbcServices再拿到Dialect的方式,在Hibernate 6.4的绝大多数运行场景下是可靠的——JdbcServices是Hibernate处理JDBC核心逻辑的基础服务,在SessionFactory初始化流程中会被正常注册到ServiceRegistry中。
避免空指针的优化写法
为了防范JdbcServices返回null的极端情况,建议增加非空判断后再执行逻辑:
public class MyTypeContributor implements TypeContributor { @Override public void contribute(TypeContributions typeContributions, ServiceRegistry serviceRegistry) { JdbcServices jdbcServices = serviceRegistry.getService(JdbcServices.class); if (jdbcServices != null) { Dialect dialect = jdbcServices.getDialect(); // 根据Dialect类型执行自定义类型注册逻辑 if (dialect instanceof MySQLDialect) { // 注册MySQL专属自定义类型 } else if (dialect instanceof PostgreSQLDialect) { // 注册PostgreSQL专属自定义类型 } } } }
模仿FunctionContributions失败的原因
在Hibernate的初始化时序中,TypeContributor的执行早于FunctionContributor,此时CurrentBaseSqlTypeIndicators还未完成初始化,因此调用getDialect()会返回null,触发空指针异常。
内容的提问来源于stack exchange,提问作者peterh
相关产品推荐
相关产品推荐

