栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

休眠问题:外键的列数必须与引用的主键相同

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

休眠问题:外键的列数必须与引用的主键相同

该错误说明一切,为了引用复合主键,您需要一个复合外键。(复合主键指出,您需要2个字段的唯一组合才能构成一个键-这样就不可能仅用1列引用一个唯一键。)

至于不确定如何通过使用xml映射文件来实现,目前大多数人都使用注释。

至于您的Java类,我假设importJobManagement拥有一个importJob,因此该类不应引用id,而应引用对象本身,如下所示:

public class importJobManagment implements Serializable {    private importJob importJob;    ...}

Java类应该只引用其他类,而不是组合键的成员-取决于从组合键到Java成员变量的映射。

更新答案:

简短的答案是不,您不能。外键的工作方式,它使您可以引用表中的特定行。并且,为了确保引用特定行,您需要一个标识,该标识只能描述一行,而不能描述其他任何一行。在SQL中,有一个用于实现此目的的结构,即唯一键。通过声明一列(或列的组合)是唯一的,您知道其/它们的组合值将是唯一的,在整个表中此值最多为1行,否则将违反约束。

因此,外键指的是单个唯一约束列,或者是跨越多个列的复合唯一键。由于所有表都已经有一个唯一键,即主键(它始终是唯一的),通常将其用于外键引用,但是任何unqiue列都可以使用。

最简单的情况是当我们要引用具有单列唯一键的表时。两个简单表A,其中一个表包含一个“ id”列,另一个表B,其中包含一个“
id”列,另一个表a_id,具有对A的“ id”列的外键。情况可能是这样的:

A:| id | |----||  1 ||  2 ||  3 |B:| id | a_id || 2  |  3   || 3  |  1   |

在这里,B中的每一行都引用A中的一行。它是直接引用,表B中a_id中的值直接对应于A’‘id’列中的值。因此,ID为2的B引用ID为3的A,依此类推。

现在让我们看一下如何使用复合唯一键引用表。让我们继续我们的示例,但是现在A具有另一列“ sec_id”,该列与“ id”一起组成了一个复合主键。

A:| id | sec_id ||----|--------|| 1  |   3    || 3  |   1    || 3  |   7    |B:| id | a_id ||----|------|| 2  |  3   |

在这种情况下,我们在B中遇到了问题。由于外键必须引用其引用的表中的一行,因此这显然行不通。值“
3”代表A中的哪一行?第一行中的sec_id?第二个或第三个ID(但在那种情况下,哪个?)?答案当然不是,B中没有足够的信息来引用A中的单个行,因此SQL只是没有。因此,不允许添加此类外键。

为了让B引用A,它需要同时引用A的’id’列和A的’sec_id’列,因为A中的一行是由其唯一的(’id’,’sec_id’ )对。因此,B看起来像这样:

| id | a_id | a_sec_id ||----|------|----------|| 1  |  1   |     3    || 2  |  3   |     1    || 3  |  3   |     7    |

现在,B拥有足够的信息来引用A中的一行,并且如数据所示,它确实可以。

再次更新:

我目前正在阅读JPA认证,并且已经阅读了有关复合键映射的章节。为了映射复合主键,您需要一个主键类,该主键类映射您的键的属性。有两种实现方法,一种是键属性也必须映射到实体本身中,另一种是将其用作嵌入式键。

我将提供代码示例,它们很好地说明了自己(它使用的是注释,您也应该这样做)。

第一个示例是具有常规id类(未嵌入)的基本示例。在这里,我们有一个Employee实体,其中的主键由一个整数id和一个国家/地区组成(如果在不同的国家/地区,两名雇员可以具有相同的id)。

@Entity@IdClass(EmployeeId.class)public class Employee {    @Id private String country    @Id    @Column(name = "EMP_ID")    private int id;    private String name;    ...}public class EmployeeId implements Serializable {    private String country;    private int id;    public EmployeeId() { }    public EmployeeId(final String country, final int id) {        this.country = country;        this.id = id;    }    //getters for the properties    public boolean equals(final Object other) {    //must be implemented    }    public int hashCode() {    //must be implemented    }}

注意:

  • 类上的@ IdClass-annotation。
  • id-class的两个属性也必须在实体中定义
  • id类必须实现equals和hashpre

可以完成此操作的另一种方法是通过嵌入式id类:

@Entitypublic class Employee {    @EmbeddedId    private EmployeeId id;    private String name;    public Employee(final String country, final int id) {        this.id = new EmployeeId(country, id);    }    public String getCountry() {        return id.getCountry();    }}@Embeddablepublic class EmployeeId {   private String country;   @Column(name = "EMP_ID")   private int id;   //constructor + getters + equals +hashCode}

注意:

  • 无需在实体中定义id属性
  • 要从实体获取id-class的属性,您需要从id-class获取它们

我更喜欢后者,因为它更紧凑并且不包含重复项,但是我不知道如何使用两者进行比较。



转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/487055.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号