- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我正在尝试对以下内容进行建模:
学生可以参加考试并获得成绩。
应该可以将同一个成绩实体分配给多个学生。
成绩存储在 map 中(在“考试”类中),其注释如下:
@ManyToMany
@MapKeyClass(value = Person.class)
@JoinTable(name = "t1")
private Map<Person, Grade> grades;
JPA 创建以下连接表:
T1:
EXAM_ID: stores the id of the exam, is part of the primary key
GRADES_ID: stores the id of the grade, is part of the primary key
GRADES_KEY: stores the id of the student, is not part of the primary key
然而,我期望的表格会有一个包含学生和考试的主键。
我现在面临的问题是当我尝试以下操作时:
grades.put(student1, grade1);
grades.put(student2, grade1);
...我会得到一个异常,告诉我我违反了数据库约束。
我如何正确保留此映射?
我使用 eclipselink 2.6.0 作为 JPA 提供程序。该应用程序在带有 derby 数据库的 glassfish 服务器上运行。
感谢您的阅读,祝您有愉快的一天:)
更新:
这些是创建数据库的 SQL 查询、eclipselink 调用:
...
CREATE TABLE EXAM_GRADE (Exam_ID BIGINT NOT NULL, grades_ID BIGINT NOT NULL, grades_KEY BIGINT, PRIMARY KEY (Exam_ID, grades_ID))
...
ALTER TABLE EXAM_GRADE ADD CONSTRAINT EXAMGRADEgrades_ID FOREIGN KEY (grades_ID) REFERENCES GRADE (ID)
ALTER TABLE EXAM_GRADE ADD CONSTRAINT EXAMGRADEgradesKEY FOREIGN KEY (grades_KEY) REFERENCES PERSON (ID)
ALTER TABLE EXAM_GRADE ADD CONSTRAINT EXAM_GRADE_Exam_ID FOREIGN KEY (Exam_ID) REFERENCES EXAM (ID)
...
最佳答案
好吧,我们这里遇到了几个问题:我在 Hibernate 上试过了,但得到的结果与你不同。我认为 Hibernate 做的是正确的,因此我对更新的第一个回答。
首先,您显示的代码不应产生您所获得的结果。当您声称 GRADES_ID
是 join table
中的 primary key
的一部分时,这不应该是真的。当我运行该示例时,我得到了 primary key (Exam_id, grades_KEY)
。
其次,您的 grades
字段中应该有一个 OneToMany
关系,而不是一个 ManyToMany
关系。当您为两个学生插入相同的成绩时,具有 ManyToMany
关系不应导致约束冲突
。当你有一个 OneToMany
关系时,将创建一个 constraint
for unique (grades_id)
,这确实会阻止你插入相同的成绩两个学生:
grades.put(student1, grade1);
grades.put(student2, grade1);
具有约束
是可取的,因为它可以防止一个学生的成绩也分配给另一个学生的编码错误。
当您考虑关系时,请考虑实体
之间的关系。在这种情况下,您有一个 Exam
和许多 Student
,因此您应该有一个 OneToMany
。
最后,MapKeyClass
是多余的,没有充分的理由自己命名您的连接表
,尤其是t1
。
你们的关系应该很简单:
@OneToMany(fetch=FetchType.EAGER)
private Map<Student, Grade> grades;
当您创建考试
时,请确保为每个学生保存唯一的成绩:
public void testCreateExam() {
Student student1 = new Student("Karl");
Grade grade1 = new Grade(85);
Student student2 = new Student("Debbie");
Grade grade2 = new Grade(90);
Map<Student, Grade> grades = new HashMap<Student, Grade>();
grades.put(student1, grade1);
grades.put(student2, grade2);
examService.createExam("Biology", grades);
}
并确保您首先坚持每个 Student
和 Grade
(或制定适当的逻辑):
public Exam createExam(String name, Map<Student, Grade> grades) {
for(Student student: grades.keySet()) {
em.persist(student);
Grade grade = grades.get(student);
em.persist(grade);
}
Exam exam = new Exam(name);
exam.setGrades(grades);
em.persist(exam);
return exam;
}
更新:
我查看了 EclipseLink 2.6。哇,完全是 FUBAR。首先,它甚至不允许我用 OneToMany
注释 Map,这是完全错误的。其次,它处理 ManyToMany
的方式与我描述的 Hibernate 处理 OneToMany
的方式完全相同。所以,我得到了 Eclipselink
版本来像 Hibernate
使用 ManyToMany
那样工作,但是我必须生成 Schema 脚本,通过手,并使用它们来创建数据库。几乎不是开发代码的好方法。
// Change the primary key to be the Exam_Id and the grades_KEY
CREATE TABLE EXAM_GRADE (Exam_ID BIGINT NOT NULL, grades_ID BIGINT NOT NULL, grades_KEY BIGINT, PRIMARY KEY (Exam_ID, grades_KEY))
// removed the constraint for grades_ID references GRADE (ID)
ALTER TABLE EXAM_GRADE ADD CONSTRAINT EXAMGRADEgradesKEY FOREIGN KEY (grades_KEY) REFERENCES PERSON (ID)
ALTER TABLE EXAM_GRADE ADD CONSTRAINT EXAM_GRADE_Exam_ID FOREIGN KEY (Exam_ID) REFERENCES EXAM (ID)
在进行这些更改后,我能够为不同的 Student
编写和读取相同的 Grade
。这些模式脚本现在正是 Hibernate 生成它们的方式。我认为在 Eclipselink 上发生了一些有趣的事情,提交一个关于这个的错误是个好主意。另外,请注意,虽然您可能想为不同的学生分配相同的分数,但这在问题领域没有意义,但这当然是我的拙见。我意识到 Java Map
将能够让不同的 keys
引用相同的 value
,所以对于某些问题来说这当然是一个可以想象的要求, Ecpliselink
似乎无法处理。
关于java - JPA:从实体到实体的 HashMap 在连接表中获取错误的主键,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35380705/
我已经使用 vue-cli 两个星期了,直到今天一切正常。我在本地建立这个项目。 https://drive.google.com/open?id=0BwGw1zyyKjW7S3RYWXRaX24tQ
您好,我正在尝试使用 python 库 pytesseract 从图像中提取文本。请找到代码: from PIL import Image from pytesseract import image_
我的错误 /usr/bin/ld: errno: TLS definition in /lib/libc.so.6 section .tbss mismatches non-TLS reference
我已经训练了一个模型,我正在尝试使用 predict函数但它返回以下错误。 Error in contrasts<-(*tmp*, value = contr.funs[1 + isOF[nn]])
根据Microsoft DataConnectors的信息我想通过 this ODBC driver 创建一个从 PowerBi 到 PostgreSQL 的连接器使用直接查询。我重用了 Micros
我已经为 SoundManagement 创建了一个包,其中有一个扩展 MediaPlayer 的类。我希望全局控制这个变量。这是我的代码: package soundmanagement; impo
我在Heroku上部署了一个应用程序。我正在使用免费服务。 我经常收到以下错误消息。 PG::Error: ERROR: out of memory 如果刷新浏览器,就可以了。但是随后,它又随机发生
我正在运行 LAMP 服务器,这个 .htaccess 给我一个 500 错误。其作用是过滤关键字并重定向到相应的域名。 Options +FollowSymLinks RewriteEngine
我有两个驱动器 A 和 B。使用 python 脚本,我在“A”驱动器中创建一些文件,并运行 powerscript,该脚本以 1 秒的间隔将驱动器 A 中的所有文件复制到驱动器 B。 我在 powe
下面的函数一直返回这个错误信息。我认为可能是 double_precision 字段类型导致了这种情况,我尝试使用 CAST,但要么不是这样,要么我没有做对...帮助? 这是错误: ERROR: i
这个问题已经有答案了: Syntax error due to using a reserved word as a table or column name in MySQL (1 个回答) 已关闭
我的数据库有这个小问题。 我创建了一个表“articoli”,其中包含商品的品牌、型号和价格。 每篇文章都由一个 id (ID_ARTICOLO)` 定义,它是一个自动递增字段。 好吧,现在当我尝试插
我是新来的。我目前正在 DeVry 在线学习中级 C++ 编程。我们正在使用 C++ Primer Plus 这本书,到目前为止我一直做得很好。我的老师最近向我们扔了一个曲线球。我目前的任务是这样的:
这个问题在这里已经有了答案: What is an undefined reference/unresolved external symbol error and how do I fix it?
我的网站中有一段代码有问题;此错误仅发生在 Internet Explorer 7 中。 我没有在这里发布我所有的 HTML/CSS 标记,而是发布了网站的一个版本 here . 如您所见,我在列中有
如果尝试在 USB 设备上构建 node.js 应用程序时在我的树莓派上使用 npm 时遇到一些问题。 package.json 看起来像这样: { "name" : "node-todo",
在 Python 中,您有 None单例,在某些情况下表现得很奇怪: >>> a = None >>> type(a) >>> isinstance(a,None) Traceback (most
这是我的 build.gradle (Module:app) 文件: apply plugin: 'com.android.application' android { compileSdkV
我是 android 的新手,我的项目刚才编译和运行正常,但在我尝试实现抽屉导航后,它给了我这个错误 FAILURE: Build failed with an exception. What wen
谁能解释一下?我想我正在做一些非常愚蠢的事情,并且急切地等待着启蒙。 我得到这个输出: phpversion() == 7.2.25-1+0~20191128.32+debian8~1.gbp108
我是一名优秀的程序员,十分优秀!