Hibernate 单向 OneToMany 不使用复合 id

Posted

技术标签:

【中文标题】Hibernate 单向 OneToMany 不使用复合 id【英文标题】:Hibernate Unidirectional OneToMany Not Working with composite id 【发布时间】:2016-05-07 01:57:48 【问题描述】:

这两天我一直在敲键盘,想弄明白...

一些背景知识:我们使用 Perl 代码库建立了一个数据模型,该代码库通过 ODBC 将本机 SQL 语句直接运行到数据库。由于某些原因,我们决定用 Java 重写代码……我认为使用 Hibernate 来定义所有映射是个好主意。我们不想编辑数据模型。

为简单起见,我可以只用我们数据模型的一部分来表达问题。我们有实体“Job”、“JobDatabase”和“JobTable”。

Job 的 PK 为 job_name。数据库的 PK 为 job_name,name。表的 P​​K 为 job_name,src_database_name,name。如您所料,Job 与 JobDatabase 具有 OneToMany 关系,Database 与 JobTable 具有 OneToMany 关系。

出于此测试的目的,我从空表开始并尝试创建一些示例数据。我可以插入 Job 和 JobDatabase,但是当我尝试插入 JobTable 时,Hibernate 会抛出错误。或者更准确地说,这就是它抱怨的地方。它不会开始执行我的代码,因为它检测到映射错误。但是,如果我删除 JobDatabase 和 JobTable 之间的关联,它将正确插入所有 Job 和 JobDatabase 记录而没有错误。

示例类(所有字段都有 getter/setter...还有很多其他字段):

@Entity
@Table(name="Job")
public class Job implements Serializable 
    @Id
    @Column(name="job_name",nullable = false)
    private String jobName;

    @OneToMany(cascade = CascadeType.ALL)
    @JoinColumn(name = "job_name", referencedColumnName = "job_name")
    private Set<JobDatabase> databases;


@Entity
@Table(name="JobDatabase")
public class JobDatabase implements Serializable 
    @Id
    @Column(name="job_name",nullable = false)
    private String jobName;

    @Id
    @Column(name="name",nullable = false)
    private String name;

    @OneToMany(cascade = CascadeType.ALL)
    @JoinColumns(
            @JoinColumn(name = "job_name", referencedColumnName = "job_name"),
            @JoinColumn(name = "name", referencedColumnName = "src_database_name")
    )
    private Set<JobTable> tables;


@Entity
@Table(name="JobTable")
public class JobTable implements Serializable
    @Id
    @Column(name="job_name",nullable = false)
    private String jobName;

    @Id
    @Column(name="src_database_name",nullable = false)
    private String srcDatabaseName;

    @Id
    @Column(name="name",nullable = false)
    private String name;

错误:

Exception in thread "main" org.hibernate.MappingException: Unable to find column with logical name: src_database_name in JobDatabase

我不断收到此错误。我不明白为什么它在“拥有”映射的实体中寻找引用的列。 src_database_name 确实只存在于 JobTable 中——它在 JobDatabase 中被称为“名称”。 JobTable 也有一个“name”字段,但它指的是 Table 的名称。

【问题讨论】:

【参考方案1】:

您需要在 JobDatabase 表中有 src_database_name 列。或者您可以将 src_database_name 更改为其他列名。

对于复合键引用列必须存在于您的源表中。

【讨论】:

以上是关于Hibernate 单向 OneToMany 不使用复合 id的主要内容,如果未能解决你的问题,请参考以下文章

删除元素时使用 JoinTable 和 OrderColumn 的 Hibernate 单向 OneToMany 映射中的约束冲突

Hibernate如何正确删除@OneToMany中的孩子?

hibernate 映射总结

Hibernate—— 一对多 和 多对多关联关系映射(xml和注解)总结(转载)

JPQL 用于单向 OneToMany

OneToMany 和 ManyToMany 单向关系的区别