OMG!我一直在想办法解决以下问题。我用Google搜索并尝试了所有可能的方法,但没有运气。
Caused by: Exception [EclipseLink-30005] (Eclipse Persistence Services - 2.3.2.v20111125-r10461): org.eclipse.persistence.exceptions.PersistenceUnitLoadingException
Exception Description: An exception was thrown while searching for persistence archives with ClassLoader: sun.misc.Launcher$AppClassLoader@93dee9
Internal Exception: javax.persistence.PersistenceException: Exception [EclipseLink-28018] (Eclipse Persistence Services - 2.3.2.v20111125-r10461): org.eclipse.persistence.exceptions.EntityManagerSetupException
Exception Description: Predeployment of PersistenceUnit [RateProfessorPU] failed.
Internal Exception: Exception [EclipseLink-7220] (Eclipse Persistence Services - 2.3.2.v20111125-r10461): org.eclipse.persistence.exceptions.ValidationException
Exception Description: The @JoinColumns on the annotated element [field professorId] from the entity class [class rateprofessor.database.entity.Rating] is incomplete. When the source entity class uses a composite primary key, a @JoinColumn must be specified for each join column using the @JoinColumns. Both the name and the referencedColumnName elements must be specified in each such @JoinColumn.
at org.eclipse.persistence.exceptions.PersistenceUnitLoadingException.exceptionSearchingForPersistenceResources(PersistenceUnitLoadingException.java:127)
at org.eclipse.persistence.jpa.PersistenceProvider.createEntityManagerFactory(PersistenceProvider.java:115)
at javax.persistence.Persistence.createEntityManagerFactory(Unknown Source)
at javax.persistence.Persistence.createEntityManagerFactory(Unknown Source)
at rateprofessor.database.DBFactory.<clinit>(DBFactory.java:27)
... 2 more
我正在使用netbeans和eclipselink(jpa 2.0)。
我附上了两个表结构。
对于Professor教授,name和departmentID是复合主键,id是自动生成的唯一键,它是评级表的外键。
以下是两个表的java类:
教授的
@Entity
@Table(name = "professor", catalog = "rateprofessor", schema = "", uniqueConstraints = {
@UniqueConstraint(columnNames = {"id"})})
@XmlRootElement
@NamedQueries({
@NamedQuery(name = "Professor.findAll", query = "SELECT p FROM Professor p"),
@NamedQuery(name = "Professor.findByName", query = "SELECT p FROM Professor p WHERE p.professorPK.name = :name"),
@NamedQuery(name = "Professor.findByDepartmentID", query = "SELECT p FROM Professor p WHERE p.professorPK.departmentID = :departmentID"),
@NamedQuery(name = "Professor.findByEmail", query = "SELECT p FROM Professor p WHERE p.email = :email"),
@NamedQuery(name = "Professor.findByPhone", query = "SELECT p FROM Professor p WHERE p.phone = :phone"),
@NamedQuery(name = "Professor.findByTitle", query = "SELECT p FROM Professor p WHERE p.title = :title"),
@NamedQuery(name = "Professor.findById", query = "SELECT p FROM Professor p WHERE p.id = :id"),
@NamedQuery(name = "Professor.findByFirstName", query = "SELECT p FROM Professor p WHERE p.firstName = :firstName"),
@NamedQuery(name = "Professor.findByLastName", query = "SELECT p FROM Professor p WHERE p.lastName = :lastName")})
public class Professor implements Serializable {
private static final long serialVersionUID = 1L;
@EmbeddedId
protected ProfessorPK professorPK;
@Column(name = "email", length = 255)
private String email;
@Column(name = "phone", length = 255)
private String phone;
@Basic(optional = false)
@Column(name = "title", nullable = false, length = 255)
private String title;
@Basic(optional = false)
@Column(name = "id", nullable = false)
private int id;
@Column(name = "firstName", length = 45)
private String firstName;
@Column(name = "lastName", length = 45)
private String lastName;
@JoinColumn(name = "departmentID", referencedColumnName = "id", nullable = false, insertable = false, updatable = false)
@ManyToOne(optional = false)
private Department department;
@OneToMany(cascade = CascadeType.ALL, mappedBy = "professorId")
private Collection<Rating> ratingCollection;
public Professor() {
}
public Professor(ProfessorPK professorPK) {
this.professorPK = professorPK;
}
public Professor(ProfessorPK professorPK, String title, int id) {
this.professorPK = professorPK;
this.title = title;
this.id = id;
}
public Professor(String name, int departmentID) {
this.professorPK = new ProfessorPK(name, departmentID);
}
public ProfessorPK getProfessorPK() {
return professorPK;
}
public void setProfessorPK(ProfessorPK professorPK) {
this.professorPK = professorPK;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public Department getDepartment() {
return department;
}
public void setDepartment(Department department) {
this.department = department;
}
@XmlTransient
public Collection<Rating> getRatingCollection() {
return ratingCollection;
}
public void setRatingCollection(Collection<Rating> ratingCollection) {
this.ratingCollection = ratingCollection;
}
@Override
public int hashCode() {
int hash = 0;
hash += (professorPK != null ? professorPK.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 Professor)) {
return false;
}
Professor other = (Professor) object;
if ((this.professorPK == null && other.professorPK != null) || (this.professorPK != null && !this.professorPK.equals(other.professorPK))) {
return false;
}
return true;
}
@Override
public String toString() {
return "rateprofessor.database.entity.Professor[ professorPK=" + professorPK + " ]";
}
}
评分
@Entity
@Table(name = "rating", catalog = "rateprofessor", schema = "")
@XmlRootElement
@NamedQueries({
@NamedQuery(name = "Rating.findAll", query = "SELECT r FROM Rating r"),
@NamedQuery(name = "Rating.findById", query = "SELECT r FROM Rating r WHERE r.id = :id"),
@NamedQuery(name = "Rating.findByDatetime", query = "SELECT r FROM Rating r WHERE r.datetime = :datetime"),
@NamedQuery(name = "Rating.findByClass1", query = "SELECT r FROM Rating r WHERE r.class1 = :class1"),
@NamedQuery(name = "Rating.findBySection", query = "SELECT r FROM Rating r WHERE r.section = :section")})
public class Rating implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Basic(optional = false)
@Column(name = "id", nullable = false)
private Integer id;
@Basic(optional = false)
@Column(name = "datetime", nullable = false)
@Temporal(TemporalType.TIMESTAMP)
private Date datetime;
@Column(name = "class", length = 45)
private String class1;
@Column(name = "section")
private Integer section;
@JoinColumn(name = "user_id", referencedColumnName = "id", nullable = false)
@ManyToOne(optional = false)
private User userId;
@JoinColumn(name = "grade", referencedColumnName = "id")
@ManyToOne
private Grade grade;
@JoinColumn(name = "comment_id", referencedColumnName = "id", nullable = false)
@ManyToOne(optional = false)
private Comment commentId;
@JoinColumn(name = "professor_id", referencedColumnName = "id", nullable = false)
@ManyToOne(optional = false)
private Professor professorId;
@OneToMany(cascade = CascadeType.ALL, mappedBy = "rating")
private Collection<RatingItem> ratingItemCollection;
public Rating() {
}
public Rating(Integer id) {
this.id = id;
}
public Rating(Integer id, Date datetime) {
this.id = id;
this.datetime = datetime;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public Date getDatetime() {
return datetime;
}
public void setDatetime(Date datetime) {
this.datetime = datetime;
}
public String getClass1() {
return class1;
}
public void setClass1(String class1) {
this.class1 = class1;
}
public Integer getSection() {
return section;
}
public void setSection(Integer section) {
this.section = section;
}
public User getUserId() {
return userId;
}
public void setUserId(User userId) {
this.userId = userId;
}
public Grade getGrade() {
return grade;
}
public void setGrade(Grade grade) {
this.grade = grade;
}
public Comment getCommentId() {
return commentId;
}
public void setCommentId(Comment commentId) {
this.commentId = commentId;
}
public Professor getProfessorId() {
return professorId;
}
public void setProfessorId(Professor professorId) {
this.professorId = professorId;
}
@XmlTransient
public Collection<RatingItem> getRatingItemCollection() {
return ratingItemCollection;
}
public void setRatingItemCollection(Collection<RatingItem> ratingItemCollection) {
this.ratingItemCollection = ratingItemCollection;
}
@Override
public int hashCode() {
int hash = 0;
hash += (id != null ? id.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 Rating)) {
return false;
}
Rating other = (Rating) object;
if ((this.id == null && other.id != null) || (this.id != null && !this.id.equals(other.id))) {
return false;
}
return true;
}
@Override
public String toString() {
return "rateprofessor.database.entity.Rating[ id=" + id + " ]";
}
}
请帮帮我。我真的需要帮助。非常感谢你。
答案 0 :(得分:1)
问题是JPA不允许您将外键用于不是目标实体ID字段的字段。在您的情况下,Rating有一个professor_id列,它是Id的外键,但Id不是主键 - embeddedId中的name和departmentID。最简单的解决方案是在ID教授内部建立ID字段 - 无论如何,就JPA而言。表本身不需要更改。
这将允许您将professor_id用作教授ID列的外键,并在JPA提供程序中保持可移植性,并仍然使用Name + departmentID作为数据库中的pk。