具有复合主键的多对多关系

问题描述 投票:0回答:1

我试图表达一种

@ManyToMany
关系,其中一个表具有复合主键。在
table_1
中,我有一个名为
table2Id
的列,它是
table_2
的外键。
table_2
中的主键是
language
id
的复合键。我不知道如何表达两个表之间的
@ManyToMany
关系。

这是“拥有”表

@Entity
@Table(name = "table_1")
class Table1(
    @Column val foo Double,
    @Column val bar: Double,
    @Column table2Id: Long,
    @ManyToMany
    @JoinTable(
        name = "table_1_table_2_link",
        joinColumns = [JoinColumn(name = "table_1_id", referencedColumnName = "id")],
        inverseJoinColumns = [JoinColumn(name = "table_2_id", referencedColumnName = "id")]
)
    val table2: List<Table2>
) {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    var id: Long = 0 
}

这是带有复合主键的表

@Embeddable
class Table2Id (
    private var id: Long,
    private var language: Languages // enum
) : Serializable


@Entity
@Table(name = "table_2",)
class Table2 (
    @EmbeddedId
    val table2Id: Table2Id,
    @Column val title String,
    @Column val tag String,
) {
    @MapsId
    val id: Long = 0

    @MapsId
    @Enumerated(EnumType.STRING)
    val language: Languages = Languages.en
}

这给了我

org.springframework.beans.factory.BeanCreationException:创建类路径资源中定义的名为“entityManagerFactory”的bean时出错[org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.class]:无法调用“org.hibernate.mapping” .PersistentClass.getTable()”因为“classMapping”为空

spring spring-boot kotlin jpa
1个回答
0
投票

当实体的定义方式或其关系的映射方式存在问题时,通常会发生此错误。

确保初始化 Table2Id。

这就是我想到的:

@Entity
@Table(name = "table_1")
class Table1(
    @Column val foo: Double,
    @Column val bar: Double)
{
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    var id: Long = 0

    // Default constructor required by Hibernate
    constructor() : this(0.0, 0.0)

    @ManyToMany
    var table2: List<Table2> = mutableListOf() // Initialize as empty list

    fun addTable2(table2: Table2) {
        this.table2 = listOf(table2)
    }
}

表2Id

@Embeddable
class Table2Id(
    @Column(name = "id")
    var id: Long,

    @Column
    @Enumerated(EnumType.STRING)
    var language: Table2.Languages
) : Serializable {

    constructor() : this(0L, Table2.Languages.en) // Required for JPA

    // Implement equals and hashCode methods
    override fun equals(other: Any?): Boolean {
        if (this === other) return true
        if (other !is Table2Id) return false

        if (id != other.id) return false
        if (language != other.language) return false

        return true
    }

    override fun hashCode(): Int {
        var result = id.hashCode()
        result = 31 * result + language.hashCode()
        return result
    }

}

表2

@Entity
@Table(name = "table_2")
class Table2() {

    @EmbeddedId
    lateinit var table2Id: Table2Id

    @Column
    var title: String = ""

    @Column
    var tag: String = ""

    constructor(id: Long, title: String, tag: String) : this() { 
        this.table2Id = Table2Id(id, Languages.en) // Initializing Table2Id
        this.title = title
        this.tag = tag
    }

    enum class Languages {
        en,
        sw
    }
}

查询结果示例

{
    "foo": 2.2,
    "bar": 2.3,
    "id": 1,
    "table2": [
        {
            "table2Id": {
                "id": 1,
                "language": "en"
            },
            "title": "My title",
            "tag": "My tag"
        }
    ]
}
© www.soinside.com 2019 - 2024. All rights reserved.