第 6 章。限制

6.1。Hibernate API 的不完整实现

为了加快 Hibernate Shards 的初始发布,我们很少使用的一些 Hibernate API 部分没有实现。当然,我们很少使用的东西可能对某些应用程序至关重要,所以如果我们让你失望了,我们表示歉意。我们致力于尽快实现 API 的其余部分。有关哪些方法未实现的详细信息,请参阅ShardedSessionImpl, ShardedCriteriaImplShardedQueryImpl.

6.2。跨分片对象图

Hibernate Shards 目前不支持跨分片对象图。

换句话说,在对象 A 和 B 位于不同分片上时创建它们之间的关联是非法的。解决方法是在 A 上定义一个属性,该属性唯一标识类型为 B 的对象,并使用该属性加载对象 B(还记得 Hibernate 出现之前的生活吗?是的,就像那样。)

例如

                --need domain for examples--
            

在某些应用程序中,您的模型可能以一种难以犯这种错误的方式构建,但在某些应用程序中,它可能更容易。这里令人恐惧的是,如果您犯了这个错误,Hibernate 会认为列表中的“错误”对象是新对象,并且,假设您为此关系启用了级联,它将在不同的分片上创建一个此对象的新版本。这是麻烦。为了帮助防止这种情况发生,我们有一个名为CrossShardRelationshipDetectingInterceptor的拦截器,它会在创建或保存的每个对象上检查跨分片关系。

不幸的是,使用CrossShardRelationshipDetectingInterceptor会产生成本。为了确定关联对象所在的碎片,我们需要从数据库中获取该对象,因此,如果您有延迟加载的关联,拦截器将在其检查期间解析这些关联。这可能非常昂贵,可能不适合生产系统。考虑到这一点,我们让您可以轻松配置是否通过我们在配置章节中提到的“hibernate.shard.enable_cross_shard_relationship_checks”属性执行此检查。如果此属性设置为“true”,则CrossShardRelationshipDetectingInterceptor将与每个ShardedSession已建立。别担心,您仍然可以注册自己的拦截器。我们预计大多数应用程序将在其开发和 QA 环境中启用此检查,并在其暂存、加载和性能以及生产环境中禁用此检查。

6.3。分布式事务

Hibernate Shards 不提供对非托管环境中的分布式事务的支持。如果您的应用程序需要分布式事务,则需要插入支持分布式事务的事务管理实现。

6.4。有状态拦截器

我们尽力确保在使用 Hibernate Shards 时,Hibernate Core 代码大体上运行良好。不幸的是,存在例外,其中一个例外是当您的应用程序需要使用org.hibernate.Interceptor来维护状态时。

有状态拦截器需要特殊处理,因为在幕后,我们正在实例化一个org.hibernate.SessionImpl每个碎片。如果我们想要一个InterceptorSession相关联,我们需要传入创建时提供的任何InterceptorInterceptorShardedSession。如果该Interceptor是有状态的,则一个Interceptor的状态将在所有SessionSessions中可见。当您考虑通常在有状态Interceptors中完成的各种事情时(例如审计),您就会明白这如何构成问题。我们的解决方案是要求用户在建立他们的

对象(实际上是ShardedSessions)时提供一个SessionStatefulInterceptorFactory。如果提供的StatefulInterceptorFactoryInterceptor实现了此接口,Hibernate Shards 将确保将InterceptorStatefulInterceptorFactory.newInstance()返回的类型的全新实例传递给幕后建立的每个SessionSession。这是一个示例

public class MyStatefulInterceptorFactory extends BaseStatefulInterceptorFactory {
    public Interceptor newInstance() {
        return new MyInterceptor();
    }
}

许多InterceptorInterceptorSession实现需要对与其相关联的InterceptorSessionInterceptor的引用。对于有状态的SessionInterceptorSession,您希望您的InterceptorInterceptorShardedSessions具有对真实(分片特定)Session的引用,而不是分片感知的InterceptorSessionShardedSessions。为了促进这一点,您可以选择让InterceptorStatefulInterceptorFactorySession构建的InterceptorInterceptor

public class MyStatefulInterceptor implements Interceptor, RequiresSession {
    private Session session;

    public void setSession(Session session) {
        this.session = session;
    }

    ... // Interceptor interface impl
}

类型实现

RequiresSession

接口。如果StatefulInterceptorFactory构建的StatefulInterceptorFactoryInterceptor

实现了此接口,Hibernate Shards 将在工厂构建它后向

public class WeatherReport {
    private int weatherReportId;  // trouble

    public int getWeatherReportId() {
        return weatherReportId;
    }

    public void setWeatherReportId(int id) {
        weatherReportId = id;
    }
}

Interceptor

public class WeatherReport {
    private Integer weatherReportId;  // goodness

    public Integer getWeatherReportId() {
        return weatherReportId;
    }

    public void setWeatherReportId(Integer id) {
        weatherReportId = id;
    }
}

提供对真实(分片特定)Session的引用。这样,您的

Interceptor

就可以安全准确地与特定碎片进行交互。这是一个示例

由于问题的基本性质,我们预计这种情况不会很快改变。