Hibernate映射:一列到多个表

2024-01-04

我有一个针对场景的“最佳实践”问题。

设想: DB 中的多个实体,例如 Document、BlogPost、Wiki 可以由个人共享。不是为每个实体创建共享表,而是创建单个共享表。问题是,如何将共享表与不同的实体进行映射?

我有三个选项,请告知哪个选项最好,以及是否有更好的选项。

Option1:创建表共享为:

SHARES  
id (unique)
entityId (non DB enforced FK to DOCUMENTS, WIKIS, POSTS etc.)
entityType
sharedBy
sharedWith
sharedDate

在这里,entityId 将是 documentId、wikiId、postId 等的外键,entityType 将标识entityId 的类型。

在创建共享到实体映射(例如 share.getDocument() 或 share.getWiki() 等)时,这在 Hibernate 建模中存在问题。

选项2:创建仅保存共享信息的表 Shares,然后创建将共享与实体关联的解析表。

SHARES
id(PK)
sharedBy
sharedWith
sharedDate
shareType (helper field for searches)

SHARES_DOCUMENTS
share_id (unique ID and FK, one to one with SHARES)
document_id (FK to DOCUMENTS)

SHARES_POST
share_id (unique ID and FK, one to one with SHARES)
post_id (FK to POSTS)

more share tables here.

因此,在休眠方面,共享对于每种共享类型都可以是一对一的(例如 share.getDocument()、share.getPost() 和 shareType 将识别哪个关系是“活动的”)

Option 3与选项 1 类似,但创建单独的列而不是实体 ID

SHARES
id (unique ID)
documentId (FK to DOCUMENTS, nullable)
postId (FK to POSTS, nullable)
wikiId (FK to WIKIS, nullable)
sharedBy
sharedWith
sharedDate
sharedType

在这里,每一列都可以映射到各自的实体,但它们可以为空。 SharedType 可以识别哪个关系是“活动的”。

所以,问题是,哪种实践是最好的,无论是数据库方面还是休眠映射(以及最终的查询,性能方面)。

谢谢 M·拉瑟


正如 TheStijn 所建议的,在研究了设置继承关系的不同方法之后,我采用了“每个类层次结构一个表”的方法,并最终得到了如下表:

SHARES
---------
id PK
shared_by FK to User
shared_with FK to User
shared_Date
document_id nullable FK to Document
post_id nullable FK to Posts
... more ids here to link to more entities
type_discriminator (values, DOCUMENT, POST ... )

在 Hibernate/Java 方面, One Share 抽象类作为...

@Entity
@Table(name="SHARES")
@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name="TYPE_DISCRIMINATOR", discriminatorType=DiscriminatorType.STRING)
public abstract class Share {
    @Id
    @Column( name="ID", nullable=false )
    @GeneratedValue(generator="system-uuid")
    @GenericGenerator(name="system-uuid", strategy = "uuid")
    private String id;

    @ManyToOne
    @JoinColumn( name="SHARED_BY", nullable=false )
    private User sharedBy;

    @ManyToOne
    @JoinColumn( name="SHARED_WITH", nullable=false )
    private User sharedWith;

    @Column(name="SHARED_DATE", columnDefinition="TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP", nullable=false)
    @Temporal(TemporalType.TIMESTAMP)
    private Date sharedDate;        
    ...

}

还有两节普通课..

@Entity
@DiscriminatorValue("DOCUMENT")
public class SharedDocument extends Share { 
    @ManyToOne
    @JoinColumn( name="DOCUMENT_ID", nullable=true )
    private Document document;
    ....

}

@Entity
@DiscriminatorValue("POST")
public class SharedPost extends Share {
    @ManyToOne
    @JoinColumn( name="POST_ID", nullable=true )
    private Post post;
    ....

}

至于用法,仅将具体类用作:

@Test
public void saveNewDocumentShare(){
    SharedDocument sharedDocument = new SharedDocument();
    sharedDocument.setDocument(document1);
    sharedDocument.setSharedBy(teacher1);
    sharedDocument.setSharedWith(teacher2);
    sharedDocument.setSharedDate(new Date());

    sharedDocument.setCreatedBy("1");
    sharedDocument.setCreatedDate(new Date());
    sharedDocument.setModifiedBy("1");
    sharedDocument.setModifiedDate(new Date());


    SharedDocument savedSharedDocument = dao.saveSharedDocument(sharedDocument);

    assertNotNull(savedSharedDocument);
    assertThat(savedSharedDocument.getId(),notNullValue());
}

@Test
public void saveNewPostShare(){
    SharedPost sharedWikiPage = new SharedWikiPage();
    sharedPost.setPost(post1);
    sharedPost.setSharedBy(teacher1);
    sharedPost.setSharedWith(teacher2);
    sharedPost.setSharedDate(new Date());

    sharedPost.setCreatedBy("1");
    sharedPost.setCreatedDate(new Date());
    sharedPost.setModifiedBy("1");
    sharedPost.setModifiedDate(new Date());


    SharedPost savedSharedPost = dao.saveSharedPost(sharedPost);

    assertNotNull(savedSharedPost);
    assertThat(savedSharedPost.getId(),notNullValue());

}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Hibernate映射:一列到多个表 的相关文章

随机推荐

  • 数字 0 在二进制浮点数格式中是什么样子?

    浮点格式 IEEE 有 32 位 第 1 位用于符号 之后 8 位用于有偏差指数 最后 23 位用于尾数 在这个尾数中 第一个 1 始终是 1 始终隐藏 这引出了我的问题 数字 0 在这种格式中是什么样子的 因为如果指数为 0 则该数字将始
  • 查找文件无法索引的原因?

    如何查找文件在 Alfresco 中索引失败的原因 除了之前的回复 如果节点无法建立索引 您可以了解原因 使用 SOLR 管理页面和模式浏览器 例如参见这里 http localhost 8080 solr4 alfresco schema
  • 在一张图中对不同范围的数据使用多个scale_colour_gradient比例

    我对 R 很陌生 所以如果我的问题中有不清楚的地方 请耐心等待 我有一个data frame 蛋白质 有 5 列 即 1 蛋白质名称 2 蛋白质 FC 3 蛋白质 pval 4 mRNA FC 5 mRNA pval 和 6 频率 我正在尝
  • Bash 脚本不会匹配正则表达式

    我有以下 bash 脚本 应该生成输出 TEST bin bash test TEST THING OBJECT X if test a zA Z0 9 a zA Z0 9 A Z s then echo BASH REMATCH 1 fi
  • Visual Studio 9.0 Beta 程序文件位于 C:\

    我在 C 根目录中有几个 Visual Studio 9 0 Beta 程序文件 eula 1028 txt eula 1031 txt eula 1033 txt eula 1036 txt eula 1040 txt eula 1041
  • 在 fullCalendar 上使用 clientEvents 方法过滤事件

    我有一个完整的日历正在运行 现在我想使用客户事件 http fullcalendar io docs event data clientEvents 过滤事件的方法如下 selecter provider somevalue events
  • 使用 HTTP 基本身份验证的 python Flask REST API 的安全性

    我的服务器上运行着 python Flask 公开了一个由 iOS 应用程序使用的 REST API 我正在使用 Flask HTTPAuth 模块进行 HTTP 基本身份验证 我想知道这有多安全 因为每个请求都会发送用户名 密码字符串 我
  • 大型backbone.js Web应用程序组织

    我目前正在开发一个基于backbone js 的大型网络应用程序 并且在组织 僵尸 等方面遇到了很多问题 因此我决定对代码进行重大重构 我已经编写了一堆辅助函数来处理 僵尸 但是 我想从头开始 为代码创建一个很好的结构 组织 我还没有找到很
  • 制作多列的表格视图

    我正在尝试创建这样的东西 其中每一行代表一个工作集 并包含重量和重复次数 用户可以通过按按钮添加新行 但我还没弄清楚如何在 tableView 中做到这一点 这就是我希望它看起来像这样 有什么建议 想法吗 有多种方法可以做到这一点 我将这样
  • 在 Ruby 中解析 JSON 字符串

    我有一个要在 Ruby 中解析的字符串 string desc someKey someValue anotherKey value main item stats a 8 b 12 c 10 有没有简单的方法来提取数据 这看起来像Java
  • 签名的 apk 中出现 ClassNotFoundException

    如果我在 Android 设备上安装并运行签名的 APK 则会收到此错误 如果我只是编译应用程序并直接在设备上运行 则不会出现此错误 似乎缺少的片段是在我的项目代码中 而不是在任何外部库中 我该如何调查该错误 我尝试重建 清理项目等 如果在
  • Java 泛型与 ArrayList 添加元素

    我有课A B C and D where B延伸A C延伸A and D延伸A 我有以下内容ArrayList每个都有一些元素 ArrayList b b ArrayList b
  • .NET Core 工具:导入项目时的 MSB3644

    我制作了一个基于 docker 容器microsoft dotnet 1 0 sdk 按照指南 我执行了dotnet new console并得到一个文件dotnet csproj dotnet restore and dotnet run
  • C++ 中的“<<”运算符是什么? [关闭]

    很难说出这里问的是什么 这个问题是含糊的 模糊的 不完整的 过于宽泛的或修辞性的 无法以目前的形式得到合理的回答 如需帮助澄清此问题以便重新打开 访问帮助中心 help reopen questions 我无法理解以下代码中运算符 long
  • 从备份 SQL Server Express 创建/恢复数据库

    我的计算机上没有 SQL Server Management Studio 我有一个数据库备份 SQL Server 2008 R2 我的计算机上安装了与 Visual Studio 2010 Ultimate 一起安装的 SQL Serv
  • Keras 中的仅偏置层

    如何在 Keras 中构建一个层 将输入 x 映射到 x b 形式的输出 其中 b 是相同维度的可训练权重 这里的激活函数也是恒等式 您始终可以通过扩展来构建自定义层tf keras layers Layer类 这就是我要做的 import
  • 如何在android中每x分钟运行一个异步任务?

    如何在特定时间运行异步任务 我想每2分钟运行一次 我尝试使用延迟发布但不起作用 tvData postDelayed new Runnable Override public void run readWebpage 100 在上面的代码中
  • SQL中如何删除重复记录

    如何删除sql中的重复记录 In SQL Server 2005以上 WITH q AS SELECT ROW NUMBER OVER PARTITION BY dup column ORDER BY dup column AS rn FR
  • 快速滑出菜单而不滑动导航栏(以编程方式)

    几天来我一直在尝试制作左侧滑出菜单 我无法让任何库与我的应用程序配合使用 因此我求助于 raywenderlich 的教程 http www raywenderlich com 78568 create slide out navigati
  • Hibernate映射:一列到多个表

    我有一个针对场景的 最佳实践 问题 设想 DB 中的多个实体 例如 Document BlogPost Wiki 可以由个人共享 不是为每个实体创建共享表 而是创建单个共享表 问题是 如何将共享表与不同的实体进行映射 我有三个选项 请告知哪