小编典典

如何使用JPA / EclipseLink与连接表建立多对多关系

java

我有2张桌子:

电影:movieID

用户:userID

这些表通过Queue表具有多对多关系,并带有一个附加属性listOrder:

队列:movieID,userID,listOrder

我正在尝试使用EclipseLink对此模型建模,但是却收到“不兼容映射”错误。这是我的代码的示例:

@Entity
@Table(name="movieinventory")
public class Movie implements Serializable
{
       private static final long serialVersionUID = 1L;

       @Id
       @GeneratedValue
       private Integer movieID;

       @OneToMany(mappedBy="movie")
       private Set moviesInQueue;

       ...Getters/Setters...
}

@Entity
@Table(name="Users")
public class User implements Serializable
{
       private static final long serialVersionUID = 1L;

       @Id
       @GeneratedValue
       private Integer userID;

       @OneToMany(mappedBy="user")
       private Set moviesInQueue;

      ...Getters/Setters...
}

@IdClass(QueueItemPK.class)
@Entity
@Table(name="queue")
public class QueueItem
{
       @Id
       @ManyToOne
       @JoinColumn(name="movieID")
       private Movie movie;

       @Id
       @ManyToOne
       @JoinColumn(name="userID")
       private User user;

       @Basic
       private String listOrder;

       ...Getters/Setters...
}

public class QueueItemPK implements Serializable
{
       private static final long serialVersionUID = 1L;

       private Movie movie;
       private User user;

       ...Getters/Setter...

       public int hashCode()
       {
           return (movie.getMovieID() + "|" + user.getUserID()).hashCode();
       }

       public boolean equals(Object obj)
       {
           if (obj == this) return true;
           if (obj == null) return false;
           if (!(obj instanceof QueueItemPK)) return false;
           QueueItemPK pk = (QueueItemPK) obj;
           return pk.movie.getMovieID() == movie.getMovieID() 
               && pk.user.getUserID() == user.getUserID();
       }
}

QueueItemPK的目的是使我可以拥有movieID和userID的复合主键。我不确定这是否是正确的方法。

这是错误: 异常描述:[类Movie]和[类QueueItem]之间遇到了不兼容的映射。
当映射的基数与其后向指针的基数不对应时,通常会发生这种情况。
我与User类有相同的错误(错误交替出现)。

当我从QueueItem中的电影和用户变量中删除@Id批注并将其他键设为主键时,它编译时不会出错。

任何建议,将不胜感激。

谢谢,BJ


阅读 219

收藏
2020-11-23

共1个答案

小编典典

首先,正如Mike Cornell所建议的那样,EmbeddedId / Class可能是更易于使用的选择。尽管如此,要回答您的问题和更正的代码:

@IdClass(QueueItemPK.class)
@Entity
@Table(name="queue")
public class QueueItem
{
       @Id
       @ManyToOne(optional=false)
       @PrimaryKeyJoinColumn(name="movieID")
       private Movie movie;

       @Id
       @ManyToOne(optional=false)
       @PrimaryKeyJoinColumn(name="userID")
       private User user;

       @Basic
       private String listOrder;

       ...Getters/Setters...
}

public class QueueItemPK implements Serializable
{
       private static final long serialVersionUID = 1L;

       @Id
       @Column(name="movieID")
       private Integer movie;
       @Id
       @Column(name="userID")
       private Integer user;

       ...Getters/Setter...

       public int hashCode()
       {
           return (movie.getMovieID() + "|" + user.getUserID()).hashCode();
       }

       public boolean equals(Object obj)
       {
           if (obj == this) return true;
           if (obj == null) return false;
           if (!(obj instanceof QueueItemPK)) return false;
           QueueItemPK pk = (QueueItemPK) obj;
           return pk.movie == movie 
               && pk.user == user;
       }
}

如您所见,它们必须具有必须匹配的ID的类型。不是很漂亮,但是可以工作。我建议对您的Set使用泛型;使ist更易于阅读,代码更安全。

2020-11-23