【问题标题】:JPA One entity for Two Tables without SecondaryTable没有 SecondaryTable 的两个表的 JPA 一个实体
【发布时间】:2021-08-14 20:03:54
【问题描述】:

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

在OOP中,这个模型由the following diagram描述

我需要将此结构映射到数据库表。

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

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

FOLDER_ATTRDOCUMENT_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>?,
    ...
)

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

【问题讨论】:

    标签: java hibernate kotlin jpa


    【解决方案1】:

    您可以保持对象模型不变,而不是在 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>?,
        ...
    )
    

    【讨论】:

      猜你喜欢
      • 2019-04-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-06-10
      • 1970-01-01
      • 1970-01-01
      • 2021-03-17
      • 2018-12-27
      相关资源
      最近更新 更多