Last 4 hours I was dealing up with this JPA problem. At last I gave up so I am asking for a help from you. I tried almost every suggested solutions what I saw so far.
I tried,
1) Mapping changes (@ManyToOne, @OneToOne, @OneToMany)
2) Cascade options (PERSIST, MERGE, ALL..)
3) Disabling Cache
3) Many other tries that are not spesific like 1,2 and 3. Just for a hope. :)
testClass
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();
}
}
Student Class
@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
Course Class
@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
Slot Class
@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 Class
@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 Class
@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
I feel so bad for coping and pasting all the codes here. I hope someone could help me about what I am missing. First part of testClass is reading from existing well-structured text files and fill related datafields.
What happens when I run a debug is; First everything goes fine, it adds students, courses, slotAndCourses to db as expected but when a slotAndCourse instance with an existing courseCode in db is created and tring to be persisted(not sure if it is the correct word) to database it gives me duplicate entry for primary key in course table.
Error looks like this:
javax.persistence.RollbackException: Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.5.2.v20140319-9ad6abd): org.eclipse.persistence.exceptions.DatabaseException javax.persistence.RollbackException: Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.5.2.v20140319-9ad6abd): org.eclipse.persistence.exceptions.DatabaseException Internal Exception: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Duplicate entry 'cse110' for key 'PRIMARY' Internal Exception: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Duplicate entry 'cse110' for key 'PRIMARY' Error Code: 1062 Error Code: 1062 Call: INSERT INTO COURSE (COURSECODE) VALUES (?) Call: INSERT INTO COURSE (COURSECODE) VALUES (?)