java - 没有 SecondaryTable 的两个表的 JPA 一个实体
问题描述
我描述了一些由文件夹和文档组成的 ECM 域模型。简单来说,文件夹可以包含文档和其他文件夹(子文件夹)。文件夹和文档都有属性。属性可以是不同的类型。
在 OOP 中,该模型由下图描述
我需要将此结构映射到数据库表。
当我尝试将Attr
实体映射到数据库中的表时,我的问题就出现了。
与实体Attr
具有多对一的关系。这意味着表必须有两个外键:和分别。Document
Folder
ATTR
DOCUMENT_FK
FOLDER_FK
因此ER图看起来像这样
以及对应的JPA映射:
package ru.max.db.folders.domain
import javax.persistence.*
@Entity
@Table(name = "ATTR_TYPE")
class AttrType(
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
val id: Long,
val name: String
)
@Entity
@Table(name = "ATTR")
class Attr(
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
val id: Long,
@ManyToOne
@JoinColumn(name = "TYPE")
val type: AttrType,
val value: String
)
@Entity
@Table(name = "DOCUMENT")
class Document(
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
val id: Long,
val type: String,
@ManyToOne
@JoinColumn(name = "PARENT_FOLDER")
val parentFolder: Folder,
@OneToMany
@JoinColumn(name = "DOCUMENT_ID")
val attrs: MutableList<Attr>?
)
@Entity
@Table(name = "FOLDER")
class Folder(
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
val id: Long,
val clazz: String,
@OneToMany
@JoinColumn(name = "FOLDER_ID")
val attrs: MutableList<Attr>?,
@OneToMany
@JoinColumn(name = "PARENT_FOLDER")
val subFolders: MutableList<Folder>?,
@OneToMany
@JoinColumn(name = "PARENT_FOLDER")
val documents: MutableList<Document>?
)
这个解决方案的问题是ATTR.FOLDER_ID
外ATTR.DOCUMENT_ID
键列必须可以为空,并且一些行将指向文件夹的属性,而另一行将指向文档的属性。这对我来说看起来不太好。
我想要的是ATTR
分成两个不同的表FOLDER_ATTR
和DOCUMENT_ATTR
. 这是对应的ER图:
但FOLDER_ATTR
具有与 相同的结构DOCUMENT_ATTR
。因此它可以用一个 JPA 实体来表示。但是我怎么能用 JPA 注释(或者,也许用 .xml)来描述这个映射呢?
当然我不能在实体上使用两个@Table
注释:Attr
@Entity
@Table(name = "DOCUMENT_ATTR")
@Table(name = "FOLDER_ATTR")
class Attr(
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
val id: Long,
@ManyToOne
@JoinColumn(name = "TYPE")
val type: AttrType,
val value: String
)
@Entity
@Table(name = "DOCUMENT")
class Document(
...
@OneToMany
@JoinColumn(name = "OBJECT_ID")
val attrs: MutableList<Attr>?
)
@Entity
@Table(name = "FOLDER")
class Folder(
...
@OneToMany
@JoinColumn(name = "OBJECT_ID")
val attrs: MutableList<Attr>?,
...
)
有可能以某种方式在这里实现我想要的吗?我不想让两个不同的类代表相同的结构只是为了适应数据库模型。
解决方案
您可以保持对象模型不变,而不是在 ATTR 表上使用两个外键,如果这对您更有意义,您可以使用两个连接表(DOCUMENT_ATTR,FOLDER_ATTR)
@Entity
@Table(name = "DOCUMENT")
class Document(
...
@OneToMany
@JoinColumn(
name = "DOCUMENT_ATTR",
joinColumns = @JoinColumn( name="document_id"),
inverseJoinColumns = @JoinColumn( name="attr_id")
)
val attrs: MutableList<Attr>?
)
@Entity
@Table(name = "FOLDER")
class Folder(
...
@OneToMany
@JoinTable(
name = "FOLDER_ATTR",
joinColumns = @JoinColumn( name="folder_id"),
inverseJoinColumns = @JoinColumn( name="attr_id")
)
val attrs: MutableList<Attr>?,
...
)
推荐阅读
- google-chrome - Google Document Viewer 显示:服务器无法处理请求,因为它格式错误
- javascript - IE11 中的 SetProperty 与 DOM 样式属性
- python - 如何使用 Python 中的循环从单独的变量创建数组?
- atom-editor - Atom,Structure-View 安装问题
- c# - C#:serialPort 每次读取新数字
- android - Android CardView 阴影不圆角
- python - 在 Blender python 中创建一个网格的哈希
- swiftui - 我应该如何获取和设置 UserDefaults 的值?
- python - 不能让基于请求的脚本生成网页中的所有图像链接
- python - 获取 ssl.SSLError: [X509] no certificate or crl found (_ssl.c:4062) in python