Java Hibernate-使用其中一个映射表的唯一属性的多个
Hibernate不允许我使用唯一字段“docket”执行联接表,无论我是否指定“referencedColumnName=“docket”“(我认为此属性的思想是告诉Hibernate要使用哪个字段,以防它不是主键) 数据库表:Java Hibernate-使用其中一个映射表的唯一属性的多个,java,sql,hibernate,postgresql,jpa,Java,Sql,Hibernate,Postgresql,Jpa,Hibernate不允许我使用唯一字段“docket”执行联接表,无论我是否指定“referencedColumnName=“docket”“(我认为此属性的思想是告诉Hibernate要使用哪个字段,以防它不是主键) 数据库表: student --------------- id (PK) | docket (UNIQUE) inscription --------------- course_id | docket inscription's PK is (course
student
---------------
id (PK) | docket (UNIQUE)
inscription
---------------
course_id | docket
inscription's PK is (course_id, docket)
course
---------------
id (PK)
以下配置会引发上述问题:
关于学生实体:
@ManyToMany
@JoinTable(
name="inscription",
joinColumns=@JoinColumn(referencedColumnName = "docket", name="docket"),
inverseJoinColumns=@JoinColumn(name="course_id", referencedColumnName = "id")
)
private List<Course> studentCourses;
这(当然)是不正确的,因为它没有指定docket是唯一字段
它应该做的是:
alter table public.inscription add constraint FKp625s5r1hmlggpgeq4x2nju91 foreign key (docket) references public.student(docket)
但我不知道我怎么能让它这么做
有什么帮助吗?
提前谢谢
(我认为这个属性的想法是告诉Hibernate使用哪个字段,以防它不是主键)
您的假设与您使用Hibernate作为JPA实现的假设相矛盾,因为下面的提取声明您必须在主键上加入。它没有提到任何关于唯一字段的内容:
2.10.4双向多关系
假设:
- 实体A引用实体B的集合
- 实体B引用实体a的集合
- 实体A是关系的所有者
- 实体A映射到名为A的表
- 实体B映射到名为B的表
摘要不是您案例中的主键,因此您无法加入。在官方文档中找到了答案 来自JPA2.0文档: 11.1.21连接柱注释 JoinColumn注释用于指定用于连接实体关联或元素的列 收藏 name注释元素定义外键列的名称。剩下的注释 元素(referencedColumnName除外)引用此列,并具有与相同的语义 用于列注释 如果缺少referencedColumnName元素,则假定外键引用主键 引用表的键 支持非引用表主键列的引用列是可选的。 使用此类映射的应用程序将无法移植。 所以,可能是Hibernate没有实现这个特性,因为它不是强制性的
我所做的修复工作是修改铭文表,用相应的主键替换每个字段。referencedColumnName通常适用于关系末尾有多个PK字段的情况,因此可以将不同的PK列与联接表中的等效列对齐。据我所知,JPA规范中没有允许使用非PK字段加入的内容;当然JPA提供商可以允许,但你的似乎不允许。谢谢你的评论!但是,据我所知,每个数据库表只能定义PK,表的其他ID需要定义为唯一的。PK和UNIQUE都被数据库实现用作索引,但区别在于数据库中数据的组织方式(对db用户是透明的)。这就是为什么我认为对于PK,JPA文档是指任何一个表的ID(PK+唯一约束)。也许,它是指一个复合PK的专栏,我误解了文档。谢谢您的回答!你能添加你引用答案的链接吗?提前谢谢!我想给源链接,但认为它很容易找到。是的,无论如何。谢谢!正如您所说,文档中说“以下映射默认值适用:…”。然而,JPA提供了不同的工具来避免使用这些默认配置,这就是我想要的。我非常确定它们应该存在,因为我想做的是直接在数据库上编写命令。如果您可以找到这些工具(注释的属性),请让我知道。再次感谢你花时间在这上面!我真的很感激。这里的术语默认值是关于持久性提供程序生成的表和列的名称,如果用户没有定义它们自己的名称。但是外键指的是主键。您也可以在中阅读此内容。
alter table public.inscription add constraint FKp625s5r1hmlggpgeq4x2nju91 foreign key (docket) references public.student
alter table public.inscription add constraint FKp625s5r1hmlggpgeq4x2nju91 foreign key (docket) references public.student(docket)