繁体   English   中英

JPA 一个实体用于两个表,没有SecondaryTable

[英]JPA One entity for Two Tables without SecondaryTable

我描述了一些由文件夹和文档组成的 ECM 域 model。 简单来说,文件夹可以包含文档和其他文件夹(子文件夹)。 文件夹和文档都有属性。 属性可以是不同的类型。

在OOP中,这个model由下图描述

而我需要把map这个结构放到数据库表中。

当我尝试将 map Attr实体添加到数据库中的表时,我的问题就出现了。 AttrDocumentFolder实体具有多对一的关系。 这意味着表ATTR必须有两个外键: DOCUMENT_FKFOLDER_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_IDATTR.DOCUMENT_ID外键列必须可以为空,并且某些行将指向文件夹的属性,而另一行将指向文档的属性。 这对我来说看起来不太好。

我想要的是将ATTR拆分为两个不同的表FOLDER_ATTRDOCUMENT_ATTR 是对应的ER图:

但是FOLDER_ATTRDOCUMENT_ATTR具有相同的结构。 因此它可以用一个 JPA 实体来表示。 但是我怎么能用 JPA 注释(或者,也许 with.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>?,
    ...
)

有可能以某种方式在这里实现我想要的吗? 我不想让两个不同的类代表相同的结构,只是为了适应数据库 model。

您可以保持 object model 原样,而不是在 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>?,
    ...
)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM