JPA/Hibernate - 多态多对一关系设计

Posted

技术标签:

【中文标题】JPA/Hibernate - 多态多对一关系设计【英文标题】:JPA/Hibernate - Polymorphic many-to-one relationship design 【发布时间】:2017-12-30 13:51:18 【问题描述】:

我正在尝试将现有的 Ruby on Rails/Active Record 组件转换为 Springboot/JPA/Hibernate 堆栈。

有一个实体模型,其中多个不相关的类型都可以应用 cmets。

在 Rails 世界中,这是通过模型内的多态关系来实现的。从数据库的角度来看,这意味着我有一个带有“commentable_id”和“commentable_type”的评论表,它们指向拥有评论的实体类型和 id。

我计划拥有一个抽象类“CommentableEntity”,所有需要支持 cmets 的实体都将扩展它。

我尝试过应用不同的继承策略,但找不到最合适的一种: - 单个表不起作用,因为具有 cmets 的实体具有不应该在同一个表中的不同属性 - 加入表感觉很尴尬,因为仅用于 CommentableEntity 的表只有一个 ID 字段(是这些实体之间唯一的共享字段)

还有其他方法可以实现这一点吗?我试图避免使用单独的多对多表模型。 apple_cmets、orange_cmets 等或单独的评论表,如 apple_comment(带有 apple_id)、orange_comment(带有 orange_id)等。

感谢您的任何建议!

【问题讨论】:

如果您想出了一个解决方案,遇到完全相同的问题并遇到您提到的所有困难,请告诉我们! 【参考方案1】:

“我计划拥有一个抽象类 'CommentableEntity',所有需要支持 cmets 的实体都将扩展它”

您可以准确地使用继承。只需使用 @MappedSuperclass 注释来注释“CommentableEntity”,它将将此实体定义为父实体。当您需要父类包含“id”、“version”、“createdAt”和“updatedAt”字段时,总是使用它。所以我认为你有类似的情况。

【讨论】:

以上是关于JPA/Hibernate - 多态多对一关系设计的主要内容,如果未能解决你的问题,请参考以下文章

SQLAlchemy学习-9.一对多和多对一关系

django--ORM表的多对一关系

休眠:多对一关系失败

与继承的单向多对一关系

JPA:获取双向多对一关系

Rails 多对一关系聚合函数(组、计数)活动记录