【发布时间】:2021-08-14 20:03:54
【问题描述】:
我描述了一些由文件夹和文档组成的 ECM 域模型。 简单来说,文件夹可以包含文档和其他文件夹(子文件夹)。文件夹和文档都有属性。属性可以是不同的类型。
在OOP中,这个模型由the following diagram描述
我需要将此结构映射到数据库表。
当我尝试将Attr 实体映射到数据库中的表时,我的问题就出现了。
Attr 与Document 和Folder 实体具有多对一 关系。
这意味着表ATTR必须有两个外键:分别为DOCUMENT_FK和FOLDER_FK。
因此 ER 图看起来像 like that
以及对应的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。 Here是对应的ER图:
但FOLDER_ATTR 与DOCUMENT_ATTR 具有相同的结构。因此它可以用一个 JPA 实体来表示。但是我怎样才能用 JPA 注释(或者,也许用 .xml)来描述这个映射呢?
当然我不能在Attr实体上使用两个@Table注解:
@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>?,
...
)
有可能以某种方式在这里实现我想要的吗?我不想让两个不同的类代表相同的结构只是为了适应数据库模型。
【问题讨论】: