来自实体类[...]的带注释元素的@JoinColumns不完整

时间:2010-08-11 19:23:19

标签: java orm jpa toplink-essentials

我使用:NetBeans IDE 6.7.1,GlassFish v2.1,Oracle 10g XE,JAVA 6 SE,JAVA 5 EE。

我对@ManyToMany注释有问题:

@ManyToMany(fetch=FetchType.EAGER)
@JoinTable(name="CUST_RENT_MOVIE", joinColumns={@JoinColumn(name="CUST_ID")}, inverseJoinColumns={@JoinColumn(name="TITLE")})
private Collection<CustRentMovie> rents = new ArrayList<CustRentMovie>();

GlassFish v2.1.1的部分输出

Exception Description: The @JoinColumns on the annotated element [private java.util.Collection vc.domain.Customer.rents] from the entity class [class vc.domain.Customer] 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 referenceColumnName elements must be specified in each such @JoinColumn.
javax.persistence.PersistenceException: Exception [TOPLINK-28018] (Oracle TopLink Essentials - 2.1 (Build b31g-fcs (10/19/2009))): oracle.toplink.essentials.exceptions.EntityManagerSetupException
Exception Description: predeploy for PersistenceUnit [vc_pu] failed.

创建数据库的脚本的一部分:

CREATE table customer
(
cust_id NUMBER(5),    
CONSTRAINT cust_pk PRIMARY KEY (cust_id),
...
)

CREATE TABLE movie
(
title VARCHAR2(50) PRIMARY KEY,
...
)

CREATE TABLE cust_rent_movie
(
title VARCHAR2(50),
cust_id NUMBER(5),
rent_date DATE DEFAULT current_date NOT NULL,
return_date DATE,
CONSTRAINT cust_rent_movie_pk PRIMARY KEY (title, cust_id, rent_date),
CONSTRAINT CustRentMovie_movie_fk FOREIGN KEY (title) REFERENCES movie ON DELETE CASCADE,
CONSTRAINT CustRentMovie_cust_fk FOREIGN KEY (cust_id) REFERENCES customer ON DELETE CASCADE
)

Customer类的代码

@Entity
@Table(name = "customer")
@SequenceGenerator(name="seq", sequenceName="cust_id_seq", allocationSize=1)
public class Customer implements Serializable
{

    @Id
    @GeneratedValue(strategy=GenerationType.SEQUENCE, generator="seq")
    @Column(name="CUST_ID")
    private int id;


    @ManyToMany(fetch=FetchType.EAGER)
    @JoinTable(name="CUST_RENT_MOVIE", joinColumns={@JoinColumn(name="CUST_ID")}, inverseJoinColumns={@JoinColumn(name="TITLE")})
    private Collection<CustRentMovie> rents = new ArrayList<CustRentMovie>();


    public Collection<CustRentMovie> getRents()
    {
        return rents;
    }

    public void setRents(Collection<CustRentMovie> rents)
    {
        this.rents = rents;
    }
...
}

我把错误的类型放在集合类CustRentMovie而不是Movie中我改变了

private Collection<CustRentMovie> rents = new ArrayList<CustRentMovie>();

private Collection<Movie> movies = new ArrayList<Movie>();

2 个答案:

答案 0 :(得分:1)

CustomerRentMovie的PK由三列组成(title,cust_id,rent_date)。 Toplink表示您需要在@JoinColumn注释中指定所有三个连接列(目前您只指定了cust_id)。

将注释更改为类似的内容会让您超过此错误。

@JoinTable(name = "CUST_RENT_MOVIE", joinColumns = {
    @JoinColumn(name = "CUST_ID"),
    @JoinColumn(name = "TITLE"),
    @JoinColumn(name = "RENT_DATE") }, inverseJoinColumns = { @JoinColumn(name = "TITLE") })
private Collection<CustRentMovie> rents = new ArrayList<CustRentMovie>();

那就是说,Pascal的问题是有效的 - 看起来你打算建立一个从客户到电影的关系,而不是客户与CUST_RENT_MOVIE的关系。

答案 1 :(得分:0)

我把错误的类型放在集合类CustRentMovie而不是Movie中我改变了

private Collection<CustRentMovie> rents = new ArrayList<CustRentMovie>();

private Collection<Movie> movies = new ArrayList<Movie>();