具有多对一关系的复合主键不支持映射错误

时间:2013-04-05 04:40:36

标签: java java-ee servlets jpa persistence

我有三个实体通过使复合主键也是其他表的外键来形成关联关系。以下是这些实体的实施:

@Entity
@Table(name = "STUDENTSCOURSES", schema = "GPA")
@NamedQuery(name = "getAllStdCrs", query = "SELECT sc FROM StudentsCourses sc")
@IdClass(StudentCourseId.class)
public class StudentsCourses implements Serializable {
private static final long serialVersionUID = 1L;

@Id
@Column(name="studentID", insertable=false, updatable= false)
private int studentID;  

@Id
@Column(name="crsID", insertable=false, updatable=false)
private int crsID;

@ManyToOne
@JoinColumn(name="STUDENTID")
Student student;

@ManyToOne
@JoinColumn(name="CRSID")
Course course;

public StudentsCourses() {
    super();
}

public void setStudentID(int studentID) {
    this.studentID = studentID;
}
public int getStudentID() {
    return studentID;
}
public void setCrsID(int crsID) {
    this.crsID = crsID;
}
public int getCrsID() {
    return crsID;
}   
}

课程实体:

@Entity
@Table(name = "COURSES", schema = "GPA")
@NamedQuery(name = "getAllCourses", query = "SELECT c FROM Course c")
public class Course implements Serializable {

private static final long serialVersionUID = 1L;

@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
@Column(name="CRSID")
private int crsID;
private String name;

@OneToMany(mappedBy="course", fetch=FetchType.LAZY)
private Set<Assesment> assesments;

@OneToMany(mappedBy="course", fetch=FetchType.LAZY)
private Set<StudentsCourses> studentCourses;

public Course() {
    super();
}

public int getCrsID() {
    return crsID;
}

public void setCrsID(int crsID) {
    this.crsID = crsID;
}

public String getName() {
    return name;
}

public void setName(String name) {
    this.name = name;
}

public void setAssesments(Set<Assesment> assesments) {
    this.assesments = assesments;
}

public Set<Assesment> getAssesments() {
    return assesments;
}

public void setStudentCourses(Set<StudentsCourses> studentCourses) {
    this.studentCourses = studentCourses;
}

public Set<StudentsCourses> getStudentCourses() {
    return studentCourses;
}
}

学生实体:

@Entity
@Table(name = "STUDENTS", schema = "GPA")
@NamedQuery(name = "getAllStudents", query = "SELECT s FROM Student s")
public class Student implements Serializable {


private static final long serialVersionUID = 1L;

@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
private int studentID;
private String studentName;

@OneToMany(mappedBy="student", fetch = FetchType.LAZY)
private Set<Assesment> assesments;

@OneToMany(mappedBy="student", fetch = FetchType.LAZY)
private Set<StudentsCourses> studentCourses;

public Student() {
    super();
}

public int getStudnetID() {
    return studentID;
}

public void setStudnetID(int stdID) {
    this.studentID = stdID;
}

public void setStudentName(String studentName) {
    this.studentName = studentName;
}

public String getStudentName() {
    return studentName;
}

public void setAssesments(Set<Assesment> assesments) {
    this.assesments = assesments;
}

public Set<Assesment> getAssesments() {
    return assesments;
}

public void setStudentCourses(Set<StudentsCourses> studentCourses) {
    this.studentCourses = studentCourses;
}

public Set<StudentsCourses> getStudentCourses() {
    return studentCourses;
}
}

当我尝试编写程序时,我收到以下错误:

[4/5/13 0:30:15:243 EDT] 00000028 webapp        E com.ibm.ws.webcontainer.webapp.WebApp logServletError SRVE0293E: [Servlet Error]-[com.gpa.app.servlet.LoginServlet]: <openjpa-2.1.1-SNAPSHOT-r422266:1141200 fatal user error> org.apache.openjpa.persistence.ArgumentException: Field "com.gpa.app.entities.Course.studentCourses" cannot declare that it is mapped by another field. Its mapping strategy (org.apache.openjpa.jdbc.meta.strats.HandlerFieldStrategy) does not support mapping by another field.

可能是问题的原因。感谢您的帮助。

1 个答案:

答案 0 :(得分:1)

所以问题出在我的@Id课程中。在那个课程中,我没有实现相等和哈希码方法,也没有实现Serializable。完成后,一切顺利。感谢Eelke,他给了我一个尝试不同版本的想法,它帮助我找到了原因。

我修改后的代码如下所示:

public class StudentCourseId implements Serializable{

private static final long serialVersionUID = 1L;
private int studentID;
private int crsID;

public StudentCourseId() {
}

public StudentCourseId(int studentID, int crsID) {
    this.studentID = studentID;
    this.crsID = crsID;
}

public void setStudentID(int studentID) {
    this.studentID = studentID;
}

public int getStudentID() {
    return studentID;
}

public void setCrsID(int crsID) {
    this.crsID = crsID;
}

public int getCrsID() {
    return crsID;
}
public int hashCode() {
    return studentID + crsID;
}

public boolean equals(Object o) {
    return ((o instanceof StudentCourseId)
            && studentID == ((StudentCourseId) o).getStudentID() && crsID == ((StudentCourseId) o)
                .getCrsID());
}
    }
 public int getCrsID() {
    return crsID;
}   
}

希望将来对某人有所帮助。

谢谢, SAS