为了加快 Hibernate Shards 的初始发布,我们很少使用的一些 Hibernate API 部分没有实现。当然,我们很少使用的东西可能对某些应用程序至关重要,所以如果我们让你失望了,我们表示歉意。我们致力于尽快实现 API 的其余部分。有关哪些方法未实现的详细信息,请参阅ShardedSessionImpl, ShardedCriteriaImpl和ShardedQueryImpl.
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 环境中启用此检查,并在其暂存、加载和性能以及生产环境中禁用此检查。
我们尽力确保在使用 Hibernate Shards 时,Hibernate Core 代码大体上运行良好。不幸的是,存在例外,其中一个例外是当您的应用程序需要使用org.hibernate.Interceptor来维护状态时。
有状态拦截器需要特殊处理,因为在幕后,我们正在实例化一个org.hibernate.SessionImpl每个碎片。如果我们想要一个Interceptor与Session相关联,我们需要传入创建时提供的任何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 }
类型实现
接口。如果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的引用。这样,您的
就可以安全准确地与特定碎片进行交互。这是一个示例
由于问题的基本性质,我们预计这种情况不会很快改变。