使用 Hibernate
TypeContributor
,如下所示(通过 Java Service Loader 机制加载)
public class MyTypeContributor implements TypeContributor {
@Override
public void contribute(TypeContributions typeContributions, ServiceRegistry serviceRegistry) {
// if Dialect is ... then ...
}
}
..我如何根据当前Dialect
“有条件地”注册类型?我看不到我可以在方法中访问
Dialect
?注意,我不想创建新的方言。
奇怪的是,在进行
功能贡献时,这些信息确实很容易获得,但对于类型贡献来说似乎并非如此。 (比较 FunctionContributions 与 TypeContributions) 休眠版本 6.4。
一个可行的尝试,复制
FunctionContributions
所做的事情,以暴露
Dialect
:public class MyTypeContributor implements TypeContributor {
@Override
public void contribute(TypeContributions typeContributions, ServiceRegistry serviceRegistry) {
Dialect dialect = typeContributions
.getTypeConfiguration()
.getCurrentBaseSqlTypeIndicators()
.getDialect();
}
}
..不幸的是,这会导致
getDialect()
方法中出现 NPE。
下面的代码确实有效(感谢zforgo),但不确定我们是否可以保证JdbcServices
始终可用?
public class MyTypeContributor implements TypeContributor {
@Override
public void contribute(TypeContributions typeContributions, ServiceRegistry serviceRegistry) {
Dialect dialect = serviceRegistry
.getService(JdbcServices.class) // May return null
.getDialect();
}
}
的解决方案。这也是 Hibernate Spatial 项目 采用的方法,因此它猜测它与 Hibernate 项目开发人员希望我们做的事情一致。 :-) Hibernate 服务在其 API 中似乎有一个脆弱的契约,特别是在其方法何时返回
null
方面。我可能在下面进行了过度检查。唉,安全总比后悔好。
public class MyTypeContributor implements TypeContributor {
@Override
public void contribute(TypeContributions typeContributions, ServiceRegistry serviceRegistry) {
Dialect dialect = getDialect(serviceRegistry);
// ...
}
private Dialect getDialect(ServiceRegistry serviceRegistry) {
JdbcServices jdbcServices = serviceRegistry.getService(JdbcServices.class);
if (jdbcServices == null) {
// JdbcServices is one of the so-called StandardServices in Hibernate so it should always be present.
// (see https://github.com/hibernate/hibernate-orm/blob/main/hibernate-core/src/main/java/org/hibernate/service/StandardServiceInitiators.java)
// Nevertheless, we make this check.
throw new RuntimeException("Unexpected: Cannot find a 'JdbcServices' in Hibernate's ServiceRegistry.");
}
Dialect dialect = jdbcServices.getDialect();
if (dialect == null) {
// Theoretically this can happen if the Hibernate JdbcServices object is not yet configured.
// Which would mean the JdbcServices does not yet have an associated JdbcEnvironment.
// In real-life we are guaranteed that it is configured.
// Nevertheless, we make this check.
throw new RuntimeException("Unexpected: Hibernate's 'JdbcService' has no 'JdbcEnvironment'. Dialect cannot be determined.");
}
return dialect;
}
}