Hibernate:如果某种方言则注册自定义类型

问题描述 投票:0回答:1

使用 Hibernate

TypeContributor
,如下所示(通过 Java Service Loader 机制加载)

public class MyTypeContributor implements TypeContributor {
    @Override
    public void contribute(TypeContributions typeContributions, ServiceRegistry serviceRegistry) {
        // if Dialect is ... then ... 
    }
}

..我如何根据当前Dialect“有条件地”注册类型?我看不到我可以在方法中访问

Dialect
注意,我不想创建新的方言。

奇怪的是,在进行

功能贡献时,这些信息确实很容易获得,但对于类型贡献来说似乎并非如此。 (比较 FunctionContributionsTypeContributions 休眠版本 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();

    }
}


java hibernate
1个回答
0
投票
zforgo建议

的解决方案。这也是 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;
    }

}

© www.soinside.com 2019 - 2024. All rights reserved.