JPA和Java - @JoinColumns错误

时间:2011-03-22 03:05:13

标签: jpa netbeans java-ee glassfish eclipselink

我目前正在尝试显示通过JPA 2.0(eclipselink)请求的信息。我使用glassfish 3.0.1和netbeans 6.9.1作为IDE。我的持久性实体是在netbeans选项“从数据库创建实体类”下创建的。我的shcema是用workbench mysql设计的,我的服务器当然是mysql。我真的无法弄清楚是什么造成了这个@JoinColumns错误。

javax.servlet.ServletException: Exception [EclipseLink-30005] (Eclipse Persistence Services - 2.0.1.v20100213-r6600): org.eclipse.persistence.exceptions.PersistenceUnitLoadingException
Exception Description: An exception was thrown while searching for persistence archives with ClassLoader: WebappClassLoader (delegate=true; repositories=WEB-INF/classes/)
Internal Exception: javax.persistence.PersistenceException: Exception [EclipseLink-28018] (Eclipse Persistence Services - 2.0.1.v20100213-r6600): org.eclipse.persistence.exceptions.EntityManagerSetupException
Exception Description: Predeployment of PersistenceUnit [myprojectPU] failed.
Internal Exception: Exception [EclipseLink-7220] (Eclipse Persistence Services - 2.0.1.v20100213-r6600): org.eclipse.persistence.exceptions.ValidationException
Exception Description: The @JoinColumns on the annotated element [field userInfo] from the entity class [class com.myproject.jpa.UserId] 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.

此部分从 [field userInfo]实体类[class com.myproject.jpa.UserId] 随机地从实体类[class com.myproject]转换为 [field userIdList] .jpa.Cell]。所以这两个类可能都有同样的问题。

以下是我的课程:

@Entity
@XmlRootElement
@Table(name = "user_id", catalog = "workitout", schema = "")
public class UserId implements Serializable {
    private static final long serialVersionUID = 1L;
    @EmbeddedId
    protected UserIdPK userIdPK;
    @Basic(optional = false)
    @Column(name = "email", nullable = false, length = 45)
    private String email;
    @Basic(optional = false)
    @Column(name = "password", nullable = false, length = 45)
    private String password;

    @ManyToMany(mappedBy = "userIdList")
    private List<Cell> cellList;

    @JoinColumn(name = "USER_INFO_id_info", referencedColumnName = "id_info", nullable = false, insertable = false, updatable = false)
    @ManyToOne(optional = false)
    private UserInfo userInfo;

    ...    
}

@Entity
@XmlRootElement
@Table(name = "user_info", catalog = "workitout", schema = "")
public class UserInfo implements Serializable {
    private static final long serialVersionUID = 1L;
    @EmbeddedId
    protected UserInfoPK userInfoPK;
    @Basic(optional = false)
    @Column(name = "fullName", nullable = false, length = 45)
    private String fullName;
    @Basic(optional = false)
    @Column(name = "city", nullable = false, length = 45)
    private String city;
    @Basic(optional = false)
    @Column(name = "gender", nullable = false, length = 10)
    private String gender;
    @Basic(optional = false)
    @Column(name = "isCoach", nullable = false)
    private boolean isCoach;
    @Column(name = "age")
    private Integer age;
    @Column(name = "description", length = 200)
    private String description;
    @Column(name = "linkImage", length = 45)
    private String linkImage;
    @Column(name = "friendList", length = 500)
    private String friendList;
    @Column(name = "coachList", length = 500)
    private String coachList;

    @JoinColumn(name = "USER_SPORT_id_sport", referencedColumnName = "id_sport", nullable = false, insertable = false, updatable = false)
    @ManyToOne(optional = false)
    private UserSport userSport;

    @OneToMany(cascade = CascadeType.ALL, mappedBy = "userInfo")
    private List<UserId> userIdList;

    ...  
}

*第一个错误已解决,但实体类[class com.myproject.jpa.Cell]。中的 [field userIdList]仍然存在。我添加了我的单元格表的代码:

import java.io.Serializable;
import java.util.List;
import javax.persistence.Basic;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlTransient;

@Entity
@XmlRootElement
@Table(name = "cell", catalog = "workitout", schema = "")
@NamedQueries({
    @NamedQuery(name = "Cell.findAll", query = "SELECT c FROM Cell c"),
    @NamedQuery(name = "Cell.findByIdCell", query = "SELECT c FROM Cell c WHERE c.idCell = :idCell"),
    @NamedQuery(name = "Cell.findByName", query = "SELECT c FROM Cell c WHERE c.name = :name")})
public class Cell implements Serializable {
    private static final long serialVersionUID = 1L;
    @Id
    @Basic(optional = false)
    @Column(name = "id_cell", nullable = false)
    private Integer idCell;
    @Basic(optional = false)
    @Column(name = "name", nullable = false, length = 45)
    private String name;

    @ManyToMany
    @JoinTable(name = "user_id_has_cell", joinColumns = {
        @JoinColumn(name = "cell_id_cell", referencedColumnName = "id_cell", nullable = false)}, inverseJoinColumns = {
        @JoinColumn(name = "USER_ID_id", referencedColumnName = "id", nullable = false),
        @JoinColumn(name = "USER_INFO_id_info", referencedColumnName = "id_info", nullable = false, insertable = false, updatable = false),
        @JoinColumn(name = "USER_SPORT_id_sport", referencedColumnName = "id_sport", nullable = false, insertable = false, updatable = false)
    })
    private List<UserId> userIdList;

    @OneToMany(cascade = CascadeType.ALL, mappedBy = "cell")
    private List<WorkoutSession> workoutSessionList;

    public Cell() {
    }

    public Cell(Integer idCell) {
        this.idCell = idCell;
    }

    public Cell(Integer idCell, String name) {
        this.idCell = idCell;
        this.name = name;
    }

    public Integer getIdCell() {
        return idCell;
    }

    public void setIdCell(Integer idCell) {
        this.idCell = idCell;
    }

    public String getName() {
        return name;
    }

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

    public List<UserId> getUserIdList() {
        return userIdList;
    }

    public void setUserIdList(List<UserId> userIdList) {
        this.userIdList = userIdList;
    }

    public List<WorkoutSession> getWorkoutSessionList() {
        return workoutSessionList;
    }

    public void setWorkoutSessionList(List<WorkoutSession> workoutSessionList) {
        this.workoutSessionList = workoutSessionList;
    }

    @Override
    public int hashCode() {
        int hash = 0;
        hash += (idCell != null ? idCell.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 Cell)) {
            return false;
        }
        Cell other = (Cell) object;
        if ((this.idCell == null && other.idCell != null) || (this.idCell != null && !this.idCell.equals(other.idCell))) {
            return false;
        }
        return true;
    }

2 个答案:

答案 0 :(得分:2)

错误消息非常清楚地描述了问题 - UserInfo有一个复合键,因此您需要为复合键的每个字段指定多个@JoinColumn,一列:

@JoinColumns({
    @JoinColumn(...),
    @JoinColumn(...)
})
@ManyToOne(optional = false)
private UserInfo userInfo;

答案 1 :(得分:0)

从错误消息中,我会尝试将以下内容添加到您的班级UserId

@JoinColumn(name = "USER_INFO_uSERSPORTidsport", referencedColumnName = "uSERSPORTidsport", nullable = false, insertable = false, updatable = false)
@ManyToOne(optional = false)
private UserSport usersport;