【发布时间】:2016-07-29 07:24:41
【问题描述】:
我们正在尝试创建两个 Gemfire 存储库,因为它们正在处理两个不同的 bean 对象,但我们希望将这两个 bean 对象存储到同一个 gemfire 区域中。
这是正确的方法吗? 如果“是”那么该怎么做?
提前致谢。
【问题讨论】:
标签: spring spring-boot gemfire spring-data-gemfire geode
我们正在尝试创建两个 Gemfire 存储库,因为它们正在处理两个不同的 bean 对象,但我们希望将这两个 bean 对象存储到同一个 gemfire 区域中。
这是正确的方法吗? 如果“是”那么该怎么做?
提前致谢。
【问题讨论】:
标签: spring spring-boot gemfire spring-data-gemfire geode
...我们希望将这两个 bean 对象存储到同一个 gemfire 区域中。这是正确的做法吗?
这是有争议的。但是,这实际上取决于您的应用程序要求和用例。它还取决于对象之间的关系。
例如,如果您有一个扩展 (is-a) Person 的 Customer,那么将 Customers 和 People 存储在同一区域中可能看起来并没有那么糟糕。
但是,如果您存储Customers 并说Purchases,其中Customer 由Purchases 组成,或者“具有”集合/列表Purchases,则更难消化。这也使得查询这个区域变得更加棘手,因为 (OQL) 查询引擎确实会检查属性/字段的对象类型信息,甚至在查询内部调用时也会检查方法调用,这可能会导致 ClassCastExceptions 和 NoSuch[Method|Field]Exceptions。所以,小心点。
在这方面我更倾向于纯粹主义者,并建议/建议您将应用程序域模型对象保存在单独的区域中,尤其是在“具有”关系的情况下。可以将数据存储在单独的区域中,并且仍然“并置”数据(即区域),特别是用于查询目的。详情请见here。
但是……
这并不是说不能实现在同一个Region中存储相似甚至不同类型的对象。
通常,您使用 @Region 注释来注释您的业务、应用程序域对象,以指定对象将存储在哪个 GemFire 缓存区域中,就像这样...
@Region("Customers")
class Customer extends Person { ... }
@Region("Purchases")
class Purchase { ... }
然后您继续定义您的存储库...
interface CustomerRepository extends GemfireRepository<Customer, Long> { .. }
interface PurchaseRepository extends GemfireRepository<Purchase, Long> { .. }
通常,当 SD Commons Repository 基础设施和 SD GemFire 的 Repository 扩展检测到 Repository 接口时,它会检查类型参数,查看应用程序域对象(即 Customer 和 Purchase),检查这些并确定要访问的区域每个应用程序域对象都属于...
要么检测并检查@Region注解属性值,要么..
使用域对象类名的“简单”名称作为区域名称(即Customer 域对象的“客户”区域)。
这决定了地区。
但是,如果您希望将 Customer 和 Purchase 对象都存储在同一区域中,则 SD GemFire 扩展了通用存储库基础架构并允许您使用 @Region 注释来注释存储库接口,如下所示...
@Region("Customers")
interface CustomerRepository extends GemfireRepository<Customer, Long> { .. }
@Region("Customers")
interface PurchaseRepository extends GemfireRepository<Purchase, Long> { .. }
在这种情况下,Customer 和 Purchase 对象都将存储在“客户”区域中,因为存储库接口上的 @Region 注释覆盖单个应用程序域对象。
在 Spring Data GemFire 中专门允许此功能是有正当理由和用例的。要了解更多信息,请阅读here。
无论你采取什么方法,你都应该仔细权衡你的选择。
希望这会有所帮助!
干杯, 约翰
【讨论】: