【发布时间】:2015-07-13 00:46:45
【问题描述】:
过去 4 小时我一直在处理这个 JPA 问题。最后我放弃了,所以我请求你的帮助。到目前为止,我几乎尝试了所有建议的解决方案。
我试过了,
1) 映射更改(@ManyToOne、@OneToOne、@OneToMany)
2) 级联选项(PERSIST、MERGE、ALL..)
3) 禁用缓存
3) 许多其他不特别的尝试,例如 1,2 和 3。只是为了希望。 :)
测试类
public class testClass {
public static void main(String[] args) {
EntityManagerFactory emf = Persistence.createEntityManagerFactory("CSE_482_Project_4_-_PersistencePU");
EntityManager em = emf.createEntityManager();
EntityTransaction tx = em.getTransaction();
File parentFile = new File("cleardata");
File[] allFiles = parentFile.listFiles();
File myFile;
int k = 1;
for(int f =0; f<allFiles.length; f++){
try {
myFile=allFiles[f];
BufferedReader br = new BufferedReader(new FileReader(myFile));
String tempDate = br.readLine();
tempDate = tempDate.substring(17);
String[] tempDateArr = tempDate.split(" ");
int day = Integer.parseInt(tempDateArr[0]);
int month = Integer.parseInt(tempDateArr[1]);
int year = Integer.parseInt(tempDateArr[2]);
Date leavingDate = new Date(year, month, day);
String studentNumber = br.readLine().substring(13);
boolean minor = true;
if (br.readLine().contains("false")) {
minor = false;
}
Student stu = new Student(studentNumber, leavingDate);
stu.setMinorDegree(minor);
tx.begin();
em.persist(stu);
tx.commit();
String currentLine;
Slot s;
Course c;
SlotAndCourse sc;
int semester = 0;
String courseCode = "";
String slotName = "";
int credit = 0;
String termTaken = "";
int yearTaken = 0;
String grade = "";
boolean semesterSet = false;
boolean courseSet = false;
boolean gradesSet = false;
int count = 0;
while ((currentLine = br.readLine()) != null) {
String[] arr = currentLine.split(" ");
if (arr[0].equals("semester")) {
semester = Integer.parseInt(arr[1]);
semesterSet = true;
} else if (arr[0].matches("^([0-9]+[a-zA-Z]+|[a-zA-Z]+[0-9]+)[0-9a-zA-Z]*$")) { // contains both latters and digits CS112
courseCode = arr[0];
slotName = arr[1];
credit = Integer.parseInt(arr[2]);
courseSet = true;
} else if (arr[0].equals("numberofattempts")) {
int n = Integer.parseInt(arr[1]);
for (int i = 0; i < n; i++) {
currentLine = br.readLine();
System.out.println(currentLine);
arr = currentLine.split(" ");
yearTaken = Integer.parseInt(arr[0]);
termTaken = arr[1];
grade = arr[2];
}
gradesSet = true;
}
if (gradesSet && courseSet && semesterSet) {
s = new Slot();
c = new Course(courseCode);
s.setCredit(credit);
s.setSemester(semester);
s.setSlotName(slotName);
s.setSlotCode("" + k);
c.setCourseCode(courseCode);
sc = new SlotAndCourse(s,c,yearTaken,termTaken);
sc.setCourse(c);
sc.setSlot(s);
sc.setGrade(grade);
tx.begin();
em.clear(); // just a try, but didn't work
em.persist(sc);
tx.commit();
courseSet = false;
semesterSet = false;
gradesSet = false;
k++;
}
}
} catch (Exception ex) {
System.out.println(ex.toString());
ex.printStackTrace();
}
}
em.close();
}
}
学生班
@Entity
@Cacheable(false)
public class Student implements Serializable {
@Id
private String studentNumber;
@Temporal(TemporalType.DATE)
private Date leavIngDate;
private boolean mInorDegree;
public Student() {
}
public Student(String studentNumber, Date leavingDate) {
this.studentNumber = studentNumber;
this.leavIngDate = leavingDate;
}
@Override
public boolean equals(Object obj) {
if (!(obj instanceof Slot)) {
return false;
}
Student other = (Student) obj;
if ((this.studentNumber == null && other.studentNumber != null) || (this.studentNumber != null && !this.studentNumber.equals(other.studentNumber))) {
return false;
}
return true;
}
@Override
public int hashCode() {
int hash = 0;
hash += (studentNumber != null ? studentNumber.hashCode() : 0);
return hash;
}
// setters and getters
课程班
@Entity
@Cacheable(false)
public class Course implements Serializable {
@Id
private String courseCode;
public Course() {
}
public Course(String courseCode) {
this.courseCode = courseCode;
}
@Override
public boolean equals(Object obj) {
if (!(obj instanceof Course)) {
return false;
}
Course other = (Course) obj;
if ((this.courseCode == null && other.courseCode != null) || (this.courseCode != null && !this.courseCode.equals(other.courseCode))) {
return false;
}
return true;
}
@Override
public int hashCode() {
int hash = 0;
hash += (courseCode != null ? courseCode.hashCode() : 0);
return hash;
}
//setters and getters
插槽类
@Entity
@Cacheable(false)
public class Slot implements Serializable {
@Id
private String slotCode;
private String slotName;
private int credIt;
private int semester;
public Slot() {
}
public Slot(String slotCode, String slotName) {
this.slotCode = slotCode;
this.slotName = slotName;
}
@Override
public boolean equals(Object obj) {
if (!(obj instanceof Slot)) {
return false;
}
Slot other = (Slot) obj;
if ((this.slotCode == null && other.slotCode != null) || (this.slotCode != null && !this.slotCode.equals(other.slotCode))) {
return false;
}
return true;
}
@Override
public int hashCode() {
int hash = 0;
hash += (slotCode != null ? slotCode.hashCode() : 0);
return hash;
//setters getters
SlotAndCourse 类
@Entity
@Cacheable(false)
public class SlotAndCourse implements Serializable {
@EmbeddedId
protected SlotAndCoursePK slotAndCoursePK;
@JoinColumn(name = "SLOTCODE", referencedColumnName = "SLOTCODE", insertable = false, updatable = false)
@ManyToOne(cascade = {CascadeType.PERSIST, CascadeType.MERGE, CascadeType.ALL})
private Slot slot;
@JoinColumn(name = "COURSECODE", referencedColumnName = "COURSECODE", insertable = false, updatable = false)
@ManyToOne(cascade = CascadeType.PERSIST)
private Course course;
private String grade;
public SlotAndCourse() {
}
public SlotAndCourse(SlotAndCoursePK slotAndCoursePK) {
this.slotAndCoursePK = slotAndCoursePK;
}
public SlotAndCourse(String slotCode, String courseCode, int yearTaken, String termTaken) {
this.slotAndCoursePK = new SlotAndCoursePK(slotCode, courseCode, yearTaken, termTaken);
}
public SlotAndCourse(Slot s, Course c, int yearTaken, String termTaken) {
this.slot = s;
this.course = c;
this.slotAndCoursePK = new SlotAndCoursePK(s.getSlotCode(), c.getCourseCode(),yearTaken,termTaken);
}
@Override
public boolean equals(Object obj) {
if(obj instanceof SlotAndCourse){
SlotAndCourse arg = (SlotAndCourse)obj;
return this.slotAndCoursePK.equals(arg.slotAndCoursePK);
}
else if(obj instanceof SlotAndCoursePK){
SlotAndCoursePK arg = (SlotAndCoursePK)obj;
return this.slotAndCoursePK.equals(arg);
}
return false;
}
@Override
public int hashCode() {
int hash = 0;
hash += (slotAndCoursePK != null ? slotAndCoursePK.hashCode() : 0);
return hash;
}
SlontAndCoursePK 类
@Embeddable
public class SlotAndCoursePK implements Serializable{
protected String slotCode;
protected String courseCode;
protected int yearTaken;
protected String termTaken;
public SlotAndCoursePK() {
}
public SlotAndCoursePK(String slotCode, String courseCode, int yearTaken, String termTaken) {
this.slotCode = slotCode;
this.courseCode = courseCode;
this.yearTaken = yearTaken;
this.termTaken = termTaken;
}
@Override
public int hashCode() {
int hash = 0;
hash += (slotCode != null ? slotCode.hashCode() : 0);
hash += (courseCode != null ? courseCode.hashCode() : 0);
return hash;
}
@Override
public boolean equals(Object object) {
// TODO: Warning - this method won't work in the case the id fields are not set
if (!(object instanceof SlotAndCoursePK)) {
return false;
}
SlotAndCoursePK other = (SlotAndCoursePK) object;
if ((this.slotCode == null && other.slotCode != null) || (this.slotCode != null && !this.slotCode.equals(other.slotCode))) {
return false;
}
if ((this.courseCode == null && other.courseCode != null) || (this.courseCode != null && !this.courseCode.equals(other.courseCode))) {
return false;
}
return true;
}
// setters and getters
我为在这里处理和粘贴所有代码而感到难过。我希望有人可以帮助我了解我所缺少的东西。 testClass 的第一部分是从现有的结构良好的文本文件中读取并填充相关的数据字段。
当我运行调试时会发生什么; 首先一切正常,它按预期将学生、课程、slotAndCourses 添加到 db,但是当创建一个带有 db 中现有 courseCode 的 slotAndCourse 实例并将其持久化(不确定它是否是正确的词)到数据库时,它给了我重复课程表中的主键条目。
错误如下所示:
javax.persistence.RollbackException: 异常 [EclipseLink-4002] (Eclipse Persistence Services - 2.5.2.v20140319-9ad6abd): org.eclipse.persistence.exceptions.DatabaseException javax.persistence.RollbackException: 异常 [EclipseLink-4002] (Eclipse Persistence Services - 2.5.2.v20140319-9ad6abd): org.eclipse.persistence.exceptions.DatabaseException 内部异常:com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException:键“PRIMARY”的重复条目“cse110” 内部异常:com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException:键“PRIMARY”的重复条目“cse110” 错误代码:1062 错误代码:1062 呼叫:插入课程(课程代码)值(?) 调用:INSERT INTO COURSE (COURSECODE) VALUES (?)
【问题讨论】:
-
现在我更了解您在做什么,因此删除了我的答案。它与您的问题无关,因此我将发表评论,如果在使用变量的位置而不是在没有其他变量用途的更高范围内声明变量,那么阅读您的代码会更容易。在您拥有它的形式中,读者的工作是阅读每个变量的所有内容,以查看它是否在其他地方使用。更重要的是,您可能会这样发现自己的问题。
-
开始前数据库是空的吗?
-
Persistence 设置设置为“Drop and Create”,因此每次它首先删除所有架构然后重新创建。这只是一个模板,我现在有点乱。我会尽快让阅读变得更简单:)
-
下面彼得解决方案的要点是,您需要从数据库中查找 Course 实体(如果存在)并使用该实体。如果您不使用从数据库读取的托管实例,JPA 将假定它是新的,因此尝试再次插入它。因此,上面的代码试图找到该课程,并且仅在它不存在时才创建一个新课程。你有什么问题?
-
Peter 的解决方案对我帮助很大。在这里发布之前,我尝试过,但只检查数据库是否存在该课程并没有解决我的问题。下面我发布了我最后的更改,我认为它现在可以工作了!非常感谢大家。 @彼得
标签: java mysql hibernate jpa eclipselink